Skip to content

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

Open
@RossWilliams

Description

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

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