Improve error message (rfc7807) (#13680)

* Add func formatErrorMessage

* Add unit test

* Commit generated code

* Fix indentation

* Using tabs

* Set error before model

* Commit generated code

* Fix tabs

* Commit generated code

* Fix tabs

* Fix tabs

* Commit generated code
This commit is contained in:
Beppe Catanese 2022-10-31 15:35:16 +01:00 committed by GitHub
parent fa4f7e07fe
commit 1de28c8a72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 169 additions and 5 deletions

View File

@ -385,6 +385,7 @@ func (a *{{{classname}}}Service) {{nickname}}Execute(r {{#structPrefix}}{{&class
newErr.error = err.Error()
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
{{^-last}}
return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHTTPResponse, newErr

View File

@ -616,3 +616,23 @@ func (e GenericOpenAPIError) Body() []byte {
func (e GenericOpenAPIError) Model() interface{} {
return e.model
}
// format error message using title and detail when model implements rfc7807
func formatErrorMessage(status string, v interface{}) string {
str := ""
metaValue := reflect.ValueOf(v).Elem()
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
// status title (detail)
return fmt.Sprintf("%s %s", status, str)
}

View File

@ -222,4 +222,22 @@ public class GoClientCodegenTest {
"func Test_openapi_PetApiService(t *testing.T) {");
}
@Test
public void verifyFormatErrorMessageInUse() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("go")
.setInputSpec("src/test/resources/3_0/go/petstore-with-problem-details.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
TestUtils.assertFileExists(Paths.get(output + "/api_pet.go"));
TestUtils.assertFileContains(Paths.get(output + "/api_pet.go"),
"newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)");
}
}

View File

@ -0,0 +1,61 @@
openapi: 3.0.0
info:
description: >-
This spec is mainly for testing Petstore server and contains fake endpoints,
models. Please do not use this for any other purpose. Special characters: "
\
version: 1.0.0
title: OpenAPI Petstore
license:
name: Apache-2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
paths:
/foo:
get:
tags:
- pet
responses:
"200":
description: response
content:
application/json:
schema:
$ref: '#/components/schemas/Foo'
"404":
description: not found
content:
application/json:
schema:
$ref: '#/components/schemas/RestServiceError'
"422":
description: validation error
content:
application/json:
schema:
$ref: '#/components/schemas/RestServiceError'
components:
schemas:
Foo:
type: string
default: foo
# RFC7807 Problem Detail
RestServiceError:
properties:
type:
description: " A URI reference that identifies the problem type"
type: string
title:
description: "A short, human-readable summary of the problem type."
type: string
status:
description: "The HTTP Status Code"
type: integer
detail:
description: "A human-readable explanation specific to this occurrence of the problem."
type: string
instance:
description: "A unique URI that identifies the specific occurrence of the problem."
type: string

View File

@ -576,3 +576,23 @@ func (e GenericOpenAPIError) Body() []byte {
func (e GenericOpenAPIError) Model() interface{} {
return e.model
}
// format error message using title and detail when model implements rfc7807
func formatErrorMessage(status string, v interface{}) string {
str := ""
metaValue := reflect.ValueOf(v).Elem()
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
// status title (detail)
return fmt.Sprintf("%s %s", status, str)
}

View File

@ -561,3 +561,23 @@ func (e GenericOpenAPIError) Body() []byte {
func (e GenericOpenAPIError) Model() interface{} {
return e.model
}
// format error message using title and detail when model implements rfc7807
func formatErrorMessage(status string, v interface{}) string {
str := ""
metaValue := reflect.ValueOf(v).Elem()
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
// status title (detail)
return fmt.Sprintf("%s %s", status, str)
}

View File

@ -126,6 +126,7 @@ func (a *DefaultApiService) FooGetExecute(r ApiFooGetRequest) (*FooGetDefaultRes
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
return localVarReturnValue, localVarHTTPResponse, newErr
}
@ -136,6 +137,7 @@ func (a *DefaultApiService) FooGetExecute(r ApiFooGetRequest) (*FooGetDefaultRes
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
return localVarReturnValue, localVarHTTPResponse, newErr
}
@ -145,6 +147,7 @@ func (a *DefaultApiService) FooGetExecute(r ApiFooGetRequest) (*FooGetDefaultRes
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
return localVarReturnValue, localVarHTTPResponse, newErr
}

View File

@ -1666,6 +1666,7 @@ func (a *FakeApiService) TestGroupParametersExecute(r ApiTestGroupParametersRequ
newErr.error = err.Error()
return localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
}
return localVarHTTPResponse, newErr

View File

@ -589,3 +589,23 @@ func (e GenericOpenAPIError) Body() []byte {
func (e GenericOpenAPIError) Model() interface{} {
return e.model
}
// format error message using title and detail when model implements rfc7807
func formatErrorMessage(status string, v interface{}) string {
str := ""
metaValue := reflect.ValueOf(v).Elem()
field := metaValue.FieldByName("Title")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s", field.Interface())
}
field = metaValue.FieldByName("Detail")
if field != (reflect.Value{}) {
str = fmt.Sprintf("%s (%s)", str, field.Interface())
}
// status title (detail)
return fmt.Sprintf("%s %s", status, str)
}