Skip to content

Commit

Permalink
refactor: return error instead of panic (swaggo#399)
Browse files Browse the repository at this point in the history
* refactor: return error instead of panic

* fix fmt check

* fix error check

* refine getPropertyName

* refine CheckSchemaType method
  • Loading branch information
easonlin404 authored and Tobias Theel committed May 27, 2019
1 parent 0049d30 commit 33d60a1
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 98 deletions.
31 changes: 20 additions & 11 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,12 @@ func (operation *Operation) parseAndExtractionParamAttribute(commentLine, schema
}
for _, e := range enums {
e = strings.TrimSpace(e)
param.Enum = append(param.Enum, defineType(schemaType, e))

value, err := defineType(schemaType, e)
if err != nil {
return err
}
param.Enum = append(param.Enum, value)
}
case "maxinum":
attr, err := findAttr(re, commentLine)
Expand Down Expand Up @@ -264,7 +269,11 @@ func (operation *Operation) parseAndExtractionParamAttribute(commentLine, schema
if err != nil {
break
}
param.Default = defineType(schemaType, attr)
value, err := defineType(schemaType, attr)
if err != nil {
return nil
}
param.Default = value
case "maxlength":
attr, err := findAttr(re, commentLine)
if err != nil {
Expand Down Expand Up @@ -321,31 +330,31 @@ func findAttrList(re *regexp.Regexp, commentLine string) ([]string, error) {
}

// defineType enum value define the type (object and array unsupported)
func defineType(schemaType string, value string) interface{} {
func defineType(schemaType string, value string) (interface{}, error) {
schemaType = TransToValidSchemeType(schemaType)
switch schemaType {
case "string":
return value
return value, nil
case "number":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
case "integer":
v, err := strconv.Atoi(value)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
case "boolean":
v, err := strconv.ParseBool(value)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
default:
panic(fmt.Errorf("%s is unsupported type in enum value", schemaType))
return nil, fmt.Errorf("%s is unsupported type in enum value", schemaType)
}
}

Expand Down
17 changes: 14 additions & 3 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,10 @@ func (parser *Parser) parseAnonymousField(pkgName string, field *ast.Field) (map
}

func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
prop := getPropertyName(field.Type, parser)
prop, err := getPropertyName(field.Type, parser)
if err != nil {
return nil, err
}
if len(prop.ArrayType) == 0 {
CheckSchemaType(prop.SchemaType)
} else {
Expand Down Expand Up @@ -1058,11 +1061,19 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
}

for _, e := range strings.Split(enumsTag, ",") {
structField.enums = append(structField.enums, defineType(enumType, e))
value, err := defineType(enumType, e)
if err != nil {
return nil, err
}
structField.enums = append(structField.enums, value)
}
}
if defaultTag := structTag.Get("default"); defaultTag != "" {
structField.defaultValue = defineType(structField.schemaType, defaultTag)
value, err := defineType(structField.schemaType, defaultTag)
if err != nil {
return nil, err
}
structField.defaultValue = value
}

if IsNumericType(structField.schemaType) || IsNumericType(structField.arrayType) {
Expand Down
68 changes: 33 additions & 35 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2149,9 +2149,7 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
err = p.ParseRouterAPIInfo("", f)
Expand All @@ -2167,11 +2165,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2190,11 +2188,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2213,11 +2211,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)
p := New("")
p.ParseRouterAPIInfo("", f)

err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2236,11 +2234,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2259,11 +2257,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2282,12 +2280,12 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)
p := New("")
p.ParseRouterAPIInfo("", f)

err = p.ParseRouterAPIInfo("", f)

assert.NoError(t, err)
ps := p.swagger.Paths.Paths

val, ok := ps["/api/{id}"]
Expand All @@ -2305,11 +2303,11 @@ func Test(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand All @@ -2336,11 +2334,11 @@ func Test3(){
}
`
f, err := goparser.ParseFile(token.NewFileSet(), "", src, goparser.ParseComments)
if err != nil {
panic(err)
}
assert.NoError(t, err)

p := New("")
p.ParseRouterAPIInfo("", f)
err = p.ParseRouterAPIInfo("", f)
assert.NoError(t, err)

ps := p.swagger.Paths.Paths

Expand Down
20 changes: 10 additions & 10 deletions property.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,46 +62,46 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
return propertyName{SchemaType: "string", ArrayType: "string"}
}

// getPropertyName returns the string value for the given field if it exists, otherwise it panics.
// getPropertyName returns the string value for the given field if it exists
// allowedValues: array, boolean, integer, null, number, object, string
func getPropertyName(expr ast.Expr, parser *Parser) propertyName {
func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
if astTypeSelectorExpr, ok := expr.(*ast.SelectorExpr); ok {
return parseFieldSelectorExpr(astTypeSelectorExpr, parser, newProperty)
return parseFieldSelectorExpr(astTypeSelectorExpr, parser, newProperty), nil
}

// check if it is a custom type
typeName := fmt.Sprintf("%v", expr)
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[typeName]; isCustomType {
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}, nil
}

if astTypeIdent, ok := expr.(*ast.Ident); ok {
name := astTypeIdent.Name
schemeType := TransToValidSchemeType(name)
return propertyName{SchemaType: schemeType, ArrayType: schemeType}
return propertyName{SchemaType: schemeType, ArrayType: schemeType}, nil
}

if ptr, ok := expr.(*ast.StarExpr); ok {
return getPropertyName(ptr.X, parser)
}

if astTypeArray, ok := expr.(*ast.ArrayType); ok { // if array
return getArrayPropertyName(astTypeArray, parser)
return getArrayPropertyName(astTypeArray, parser), nil
}

if _, ok := expr.(*ast.MapType); ok { // if map
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}

if _, ok := expr.(*ast.StructType); ok { // if struct
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}

if _, ok := expr.(*ast.InterfaceType); ok { // if interface{}
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}

panic("not supported" + fmt.Sprint(expr))
return propertyName{}, errors.New("not supported" + fmt.Sprint(expr))
}

func getArrayPropertyName(astTypeArray *ast.ArrayType, parser *Parser) propertyName {
Expand Down
Loading

0 comments on commit 33d60a1

Please sign in to comment.