I’m working on a project where I use NSwag studio to genrate a TypeScript client from my Api swagger.
My api uses a custom error model. I need to ensure that the typescript client correctly binds this custom error model when exexption oaccur, rathe than using the defult error handling.
I want to use my custom eror model (Error Responser) in the Api’s swagger
Ensure the type script client geanrated by Nswag studio recognizes this custom error model in its exexption handling
modify the genarted client code to map API erorr resposnse to my custom error class
Can someone guid me how to proerly configure Nswag studio for this use case.
Here are my Nswag settings screenshots
Here is CustomErrorResultException code
// CustomErrorExtension.ts
import { ApiException } from '../CustomErrorExtension';
import { IErrorResult } from '../../api/IErrorResult';
export class CustomErrorResultException extends ApiException implements IErrorResult {
public Messages: string[];
public Source?: string;
public Exception?: string;
public ErrorId?: string;
public SupportMessage?: string;
public StatusCode: string;
constructor(message: string, statusCode: string, details?: any, errorResult?: IErrorResult) {
super(message, statusCode, details);
// Map ApiException properties to ErrorResult properties
this.Messages = errorResult?.messages ?? [];
this.Source = errorResult?.source;
this.Exception = errorResult?.exception;
this.ErrorId = errorResult?.errorId;
this.SupportMessage = errorResult?.supportMessage;
this.StatusCode = errorResult?.statusCode ?? statusCode;
// Ensure Messages is always an array
if (!Array.isArray(this.Messages)) {
this.Messages = [this.Messages];
}
}
static fromApiResponse(apiResponse: any): CustomErrorResultException {
const errorResult: IErrorResult = {
messages: [],
exception: 'An unexpected error occurred',
statusCode: '500',
};
if (apiResponse && typeof apiResponse === 'object') {
errorResult.messages = apiResponse.messages || [];
errorResult.exception = apiResponse.exception || 'An unexpected error occurred';
errorResult.statusCode = apiResponse.statusCode?.toString() || '500';
}
return new CustomErrorResultException(
apiResponse?.message || 'An unknown error occurred',
apiResponse?.status || 500,
undefined,
errorResult
);
}
}
// Extend SwaggerException to include ErrorResult properties
class ExtendedSwaggerException extends Error implements IErrorResult {
messages!: string[];
source?: string | undefined;
exception?: string | undefined;
errorId?: string | undefined;
supportMessage?: string | undefined;
email?: string | undefined;
statusCode?: string | undefined;
constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
super(message);
// Map SwaggerException properties to ErrorResult properties
this.message = result.messages || [];
this.source = result.source;
this.exception = result.exception;
this.errorId = result.errorId;
this.supportMessage = result.supportMessage;
this.statusCode = result.statusCode?.toString() || '500';
// Ensure Messages is always an array
if (!Array.isArray(this.message)) {
this.messages = [this.message];
}
}
}
// Replace the original SwaggerException with ExtendedSwaggerException
export class SwaggerException extends ExtendedSwaggerException {}
async function login(params: { username: string; password: string }): Promise<[number, any]> {
const request = new TokenRequest();
request.email = params.username;
request.password = params.password;
try {
const response = await tokensClient.tokens_GetToken(request);
return [200, response];
} catch (error: unknown) {
debugger;
if (error instanceof CustomErrorResultException) {
// Return the custom error as-is
return [
error.status,
error.errorResult
];
} else if (error instanceof SwaggerException) {
// Convert SwaggerException to CustomErrorResultException
const customError = CustomErrorResultException.fromApiResponse({
messages: error.message.split('n'),
exception: error.name,
statusCode: error.statusCode,
});
// Return the custom error
return [
customError.status,
customError.errorResult
];
} else if (error instanceof ApiException) {
// Convert ApiException to CustomErrorResultException
const customApiError = CustomErrorResultException.fromApiResponse({
messages: error.message.split('n'),
exception: error.name,
statusCode: error.status.toString(),
});
// Return the custom error
return [
customApiError.status,
customApiError.errorResult
];
} else {
// Handle other error types
const errorMessage = error instanceof Error ? error.message : String(error);
const customError = CustomErrorResultException.fromApiResponse({
messages: [errorMessage],
exception: 'An unexpected error occurred',
statusCode: '500',
});
return [
customError.status,
customError.errorResult
];
}
}
}
Here is auto genrated code by Nswag Studio
class SwaggerException extends Error {
override message: string;
status: number;
response: string;
headers: { [key: string]: any; };
result: any;
constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {
super();
this.message = message;
this.status = status;
this.response = response;
this.headers = headers;
this.result = result;
}
protected isSwaggerException = true;
static isSwaggerException(obj: any): obj is SwaggerException {
return obj.isSwaggerException === true;
}
}
function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {
throw new SwaggerException(message, status, response, headers, result);
}