Customize Error Handling
Below is a structured guide on how to configure and customize error handling in Speakeasy-generated SDKs.
Default Error Handling (no configuration)
By default, Speakeasy SDKs handle errors as follows:
- Validation Errors: If the server response doesn’t match the SDK’s expected data schema, validation errors will be raised.
- 4XX and 5XX Status Codes: Responses with these status codes are treated as errors.
- Connection Errors: If the SDK fails to connect to your server (DNS, timeouts, TLS errors), it raises a connection-related error/exception.
Example OpenAPI file
openapi: 3.1.0info:title: The Speakeasy Barversion: 1.0.0servers:- url: https://speakeasy.barpaths:/drinks:get:operationId: listDrinkssummary: Get a list of drinksresponses:"200":description: A list of drinkscontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink"components:schemas:Drink:type: objecttitle: Drinkproperties:name:type: string
TypeScript SDK Default Error Handling
import { Drinks } from "drinks";import {SDKValidationError,SDKError,HTTPClientError,} from "drinks/models/errors/index.js";const drinks = new Drinks();async function run() {let result;try {result = await drinks.listDrinks();console.log(result);} catch (err) {// 1. Validation Errors: Server response didn't match the SDK's expected data schemaif (err instanceof SDKValidationError) {// Raw value will be type `unknown`console.error(err.rawValue);// Validation errors can be pretty-printedconsole.error(err.pretty());return;}// 2. 4XX and 5XX Status Codes: Server returned an error code an unexpected content type// Use `typescript.defaultErrorName` to change the name of `SDKError` in `gen.yaml`if (err instanceof SDKError) {console.error(err.statusCode);console.error(err.rawResponse.body);return;}// 3. Connection Errors: The SDK didn't even get a response from the serverif (err instanceof HTTPClientError) {console.error(err.name);console.error(err.message);}throw err;}}
Recommended Configuration
To improve the DX for the end user of the SDK, we recommend that you have named error classes for certain types of errors eg UnauthorizedError
, NotFoundError
, etc. It is also common that your API will return structured JSON errors for your 4XX responses. Here is an example of how you could configure this in your OpenAPI document:
openapi: 3.1.0info:title: The Speakeasy Barversion: 1.0.0servers:- url: https://speakeasy.barpaths:/drinks:get:operationId: listDrinkssummary: Get a list of drinksresponses:"200":description: A list of drinkscontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink""401":content:application/json:schema:$ref: "#/components/schemas/UnauthorizedError""403":content:application/json:schema:$ref: "#/components/schemas/ForbiddenError""404":content:application/json:schema:$ref: "#/components/schemas/NotFoundError""429":content:application/json:schema:$ref: "#/components/schemas/TooManyRequestsError"components:schemas:Drink:type: objecttitle: Drinkproperties:name:type: stringUnauthorizedError:type: objecttitle: UnauthorizedErrorproperties:message:type: stringx-speakeasy-error-message: trueForbiddenError:type: objecttitle: ForbiddenErrorproperties:message:type: stringx-speakeasy-error-message: trueNotFoundError:type: objecttitle: NotFoundErrorproperties:message:type: stringx-speakeasy-error-message: trueTooManyRequestsError:type: objecttitle: TooManyRequestsErrorproperties:message:type: stringx-speakeasy-error-message: true
Note, we don’t tend to recommend defining 5XX responses as your server is not always in control of the response. If you do specify a JSON schema for a 5XX response and the response doesn’t match the schema, the SDK will raise a SDKValidationError
.
Note the use of x-speakeasy-error-message: true
to configure the error message to be used by the SDK, which will be propagated to err.message
in the SDK.
TypeScript SDK Default Error Handling
import { Drinks } from "drinks";import {SDKValidationError,SDKError,HTTPClientError,UnauthorizedError,ForbiddenError,NotFoundError,TooManyRequestsError,} from "drinks/models/errors/index.js";const drinks = new Drinks();async function run() {let result;try {result = await drinks.listDrinks();console.log(result);} catch (err) {// Unauthorizedif (err instanceof UnauthorizedError) {console.error(err.message);return;}// Forbiddenif (err instanceof ForbiddenError) {console.error(err.message);return;}// Not Foundif (err instanceof NotFoundError) {console.error(err.message);return;}// Too Many Requestsif (err instanceof TooManyRequestsError) {console.error(err.message);return;}// 1. Validation Errors: Server response didn't match the SDK's expected data schemaif (err instanceof SDKValidationError) {// Raw value will be type `string`console.error(err.rawValue);// Validation errors can be pretty-printedconsole.error(err.pretty());return;}// 2. 4XX and 5XX Status Codes: Server returned an error code an unexpected content type// Use `typescript.defaultErrorName` to change the name of `SDKError` in `gen.yaml`if (err instanceof SDKError) {console.error(err.statusCode);console.error(err.rawResponse.body);return;}// 3. Connection Errors: The SDK didn't even get a response from the serverif (err instanceof HTTPClientError) {console.error(err.name);console.error(err.message);}throw err;}}
Advanced Configuration
Renaming Generated Error Classes
Any unhandled API Error will raise a exception of the default SDKError
/APIError
/APIException
class depending on the SDK language. To change the name of the default error class, edit the defaultErrorName
parameter in your gen.yaml
file for the corresponding SDK language:
python:defaultErrorName: MyError
To rename other generated error classes, please refer to the Customizing Types documentation to rename generated error classes.
Handling the Default Error Response
The default
response code is a catch-all for any status code not explicitly defined. By default, Speakeasy SDKs treat default responses as non-error responses. To treat it as a specific error type, define the default response in the x-speakeasy-errors
extension on any operation:
x-speakeasy-errors:statusCodes:- "default"
Disabling Default Error Handling
In certain cases, you may want to disable the default error handling behavior of SDKs. For example, you may not want to throw an error for a 404 status code.
You can use the x-speakeasy-errors
extension to override the default error-handling behavior of SDKs.
Apply the x-speakeasy-errors
extension at the paths
, path item
, or operation
level. Deeper levels merge or override parent behavior.
The x-speakeasy-errors
extension is an object with the following properties:
Property | Type | Description |
---|---|---|
override | boolean | If true , the statusCodes list overrides any parent x-speakeasy-errors extension for this object and its children. Defaults to false . |
statusCodes | [string] | An array of status codes to handle as errors. Merges with any parent x-speakeasy-errors extension unless override is true . Each status code must be in quotation marks (e.g., "503" ) for JSON and YAML compatibility. Wildcards (e.g., 5XX ) are supported. |
If the statusCodes
array contains undocumented status codes, the SDK returns an SDK error object with the status code, response body as a string, and the raw response object. Otherwise, if content-type
is application/json
, it returns an error object from the response object in the OpenAPI document.
Example:
paths:x-speakeasy-errors:statusCodes: # Defines status codes to handle as errors for all operations- 4XX # Wildcard to handle all status codes in the 400-499 range- 5XX/drinks:x-speakeasy-errors:override: true # Forces this path and its operations to only handle 404 and 500 as errors, overriding the parent x-speakeasy-errors extension at the paths levelstatusCodes:- 404- 500get:x-speakeasy-errors:statusCodes: # As override is not set to true, this operation will handle 404, 401, 500, and 503 as errors, merging with the parent x-speakeasy-errors extension at the path item level- 401- 503operationId: getDrinksresponses:200:description: OKcontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink"401:description: Unauthorizedcontent:application/json: # As an application/json response is defined, the schema will generate a custom error object (for example `AuthError`) that will be returned and can be tested forschema:$ref: "#/components/schemas/AuthError"404:description: Not Found # As no application/json response is defined, the SDK will return a standard SDK error object.500:description: Internal Server Errorcontent:application/json:schema:$ref: "#/components/schemas/Error"503:description: Service Unavailable
Another way to disable default error handling is to set the clientServerStatusCodesAsErrors
option to false
in your gen.yaml
file for the SDK language:
go:clientServerStatusCodesAsErrors: false