swagger-api / swagger-api/swagger-codegen

[codegen] .yaml input files containing a tab character are -- without warning -- erroneously treated as JSON

Open
#6,490 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

Codegen fails to provide an error message when YAML parsing fails -- e.g. if they have a tab value in a string value (not indentation).

The assumption is that such parse errors indicate that the file is really JSON, and that may produce desired behavior in many cases. However, for YAML files with light formatting errors, this behavior gives the mistaken impression that swagger-codegen simply doesn't understand YAML. Parsing YAML as JSON just isn't possible.

This is especially confusing behavior, because not all YAML parsers choke on tabs in this way (i.e. I was able to use yaml2json on the same file without incident, and the resulting JSON was accepted by swagger-codegen).

Swagger-codegen version

2.2.2 on OSX, installed via Homebrew

Swagger declaration file content or url

my-input.yaml:

swagger: '2.0'
info:
  description:	The first character after the colon on this line is a tab
Command line used for generation

swagger-codegen generate -i my-input.yaml -l ruby -v

Example:

 $ swagger-codegen generate -i my-input.yaml -l ruby -v
[main] INFO io.swagger.codegen.config.CodegenConfigurator - 
VERBOSE MODE: ON. Additional debug options are injected
 - [debugSwagger] prints the swagger specification as interpreted by the codegen
 - [debugModels] prints models passed to the template engine
 - [debugOperations] prints operations passed to the template engine
 - [debugSupportingFiles] prints additional data passed to the template engine
[main] INFO io.swagger.parser.Swagger20Parser - reading from testrail-swagger.yaml
[main] INFO io.swagger.parser.Swagger20Parser - reading from testrail-swagger.yaml
[main] ERROR io.swagger.parser.SwaggerCompatConverter - failed to read resource listing
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'swagger': was expecting ('true', 'false' or 'null')
 at [Source: testrail-swagger.yaml; line: 1, column: 9]
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1702)
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:558)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidToken(UTF8StreamJsonParser.java:3524)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2686)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:878)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:772)
	at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3834)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3783)
	at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:2431)
	at io.swagger.parser.SwaggerCompatConverter.readResourceListing(SwaggerCompatConverter.java:189)
	at io.swagger.parser.SwaggerCompatConverter.read(SwaggerCompatConverter.java:116)
	at io.swagger.parser.SwaggerParser.read(SwaggerParser.java:74)
	at io.swagger.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:419)
	at io.swagger.codegen.cmd.Generate.run(Generate.java:232)
	at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:41)
Exception in thread "main" java.lang.RuntimeException: missing swagger input or config!
	at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:651)
	at io.swagger.codegen.cmd.Generate.run(Generate.java:234)
	at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:41)

Steps to reproduce
  1. Save the snippet above to my-input.yaml. Note that there is a tab character on the last line between the : and the T.
  2. swagger-codegen generate -i my-input.yaml -l ruby -v

Expected behavior: Successful code generation or YamlParseException
Actual behavior: JsonParseException

Note that according to the YAML spec, "tabs are forbidden". It's entirely reasonable for swagger to reject my file, but it should do so with some explicit messaging as to the YAML error.

Continuing
  1. yaml2json my-input.yaml > my-input.json
  2. swagger-codegen generate -i my-input.json -l ruby

Expected behavior: Successful code generation
Actual behavior: Successful code generation

Related issues/PRs

None that I could find in about 4 minutes of looking. And by that I mean: I saw a few hundred issues in searches for "yaml" and "json", but I was unqualified to claim that they were the same as this issue without attempting to reproduce each individual one.

Suggest a fix/enhancement

If a file is being parsed as YAML (based on its extension or whatever swagger uses to detect the format), and that parsing fails, print that parse error to STDERR before falling back on the JSON parser.

If verbose mode is on, say explicitly that "YAML parsing failed".

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the provided my-input.yaml and swagger-codegen generate command, then start at SwaggerCompatConverter.readResourceListing and the CodegenConfigurator.toClientOptInput call shown in the stack trace. Trace the YAML failure and JSON fallback; done means the YAML parse error is reported explicitly instead of only exposing JsonParseException, with the existing valid JSON path preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, yaml
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.