Skip to content

OpenApi onErrorStatusConflict: OneOf transforms errors into a tagged union #2512

Closed
@RossWilliams

Description

@RossWilliams

Setting openApi configuration parameter onErrorStatusConflict to oneOf transforms the error shapes under the same http status code to a tagged union set. However, server SDKs do not generate tagged unions for errors, leading to a mismatch between client and server. Additionally, Smithy Errors are not tagged unions. They are designed as an array of possible outputs, with the shape name providing the discriminating tag. I believe the problem occurs because the code generation relies on the UnionShape, which are a distinct concept from the errors array.

namespace example

 use aws.protocols#restJson1
 use smithy.framework#ValidationException

 @restJson1
 service Example {
     version: "2006-03-01",
     operations: [Op],
     errors: [
         Error1,
         Error2
     ]
 }

@http(uri: "/op", method: "GET")
 operation Op {
     input: String,
     output: String
 }

 @httpError(418)
 structure Error1 {
     TeapotName: String
 }

 @httpError(418)
 structure Error2 {
     IsHot: Boolean
 }
{
   "openapi": "3.0.2",
   "info": {
     "title": "Example",
     "version": "2006-03-01"
   },
   "paths": {
     "/op": {
       "get": {
         "operationId": "Op",
         "responses": {
           "200": {
             "description": "GetOp 200 response",
             "content": {
               "application/json": {
                 "schema": {
                   "$ref": "#/components/schemas/GetOpResponseContent"
                 }
               }
             }
           },
           "418": {
             "description": "GetOp418Error 418 response",
             "content": {
               "application/json": {
                 "schema": {
                   "$ref": "#/components/schemas/GetOp418ErrorResponseContent"
                 }
               }
             }
           }
         }
       }
     }
   },
   "components": {
     "schemas": {
       "Error1": {
         "type": "object",
         "properties": {
           "TeapotName": {
             "type": "string"
           }
         }
       },
       "Error2": {
         "type": "object",
         "properties": {
           "IsHot": {
             "type": "boolean"
           }
       },
       "GetOp418ErrorResponseContent": {
         "oneOf": [
           {
             "type": "object",
             "title": "Error1",
             "properties": {
               "Error1": {
                 "$ref": "#/components/schemas/Error1"
               }
             },
             "required": [
               "Error1"
             ]
           },
           {
             "type": "object",
             "title": "Error2",
             "properties": {
               "Error2": {
                 "$ref": "#/components/schemas/Error2"
               }
             },
             "required": [
               "Error2"
             ]
           }
         ]
       },
       "GetOpResponseContent": {
         "type": "string"
       }
     }
   }
 }

Issue introduced in #1995 . Creating a tagged union of errors is not necessary for OpenApi per this comment.

The correct output shape for the 418 component is:

"GetOp418ErrorResponseContent": {
   "oneOf": [
     {
         "$ref": "#/components/schemas/Error1"
     },
     {
         "$ref": "#/components/schemas/Error2"
     }
   ]
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions