Error handling examples
IBM Financial Services Workbench offers the handling of these main types of errors:
Business errors which can occur if business conditions are not met but are expected to happen
Validation errors
General errors (all others)
Error handling logic can be implemented in several places:
Domain services or commands within their
handleError()
methodAPI operation class within its
handleError()
methodAPI ErrorMiddleware class within its
handleError()
method
Domain error handling
Inside a domain namespace a business error can be thrown whenever a domain service or a command can/should not be executed due to conditions that are not fulfilled, e.g., minimumAmountOrdered should be 5 but customer inputs 4.
You can create as many business errors as needed.
Within the implementation file of a domain service or a command you can paste the following code to throw a business error:
throw this.factory.error.nsacrnm.MyBusinessError();
where nsacronym
must get replaced with the acronym of the domain namespace in which you created the business error
and MyBusinessError
gets replaced with the actual name of the business error you want to throw (and have defined
previously in the design model).
Every error thrown in an implementation file will be handled by the handleError
method of the implementation that
receives the error (if not yet handled otherwise). In the following example the domain namespace is called orderm
and
the business error thrown in the domain service is called NoOrdersAvailable
. So at the end of the implementation file
of the API operation the code would look similar to this:
...
/**
* This function is automatically called when an error occurs within the execution flow of an operation
* @param error Operation execution error that occurred.
*/
public async handleError(error: Error): Promise<void> {
const log = this.util.log;
// First check if the error received is a business error
if (this.isInstanceOf.error.BusinessError(error)) {
// Now check if the received error is a NoOrdersAvailable error
if (this.isInstanceOf.businessError.orderm.NoOrdersAvailable(error)) {
// do something special because this business error was thrown
}
}
If you need to check for other error types (e.g., validation errors, etc.) please see TypeScript Solution Framework (SDK) - isInstanceOf checks for further details.
Error Middleware
ErrorMiddleware provides a centralized place for common error handling logic independent of API operation context.
Path of this file will be src-impl/api/API-namespace-prefix/middleware/ErrorMiddleware
. Within
ErrorMiddleware handleError()
general error handling logic can be implemented by checking the passed operation
execution error that occurred and setting response accordingly.
handleError()
method will be executed only if the API Operation's handleError()
method is not
implemented / did not set a proper response.If ErrorMiddleware handleError()
is not implemented / did not set a proper API operation response, then the original
error will be returned as API operation response with a 400 / 500 status code depending on error type (system error /
business error / validation error). An API operation response set within this class via (this.response) might end up
being an undocumented API response for the executed operation. Please make sure the response status code and schema you
set have been modelled and added to all the API namespace operations.
The class hierarchy of errors consists of GeneralError, ValidationError and BusinessError, where ValidationError and BusinessError extend GeneralError. See below example:
/**
* This class is responsible for providing a centralized place for common
* error handling logic independent from API operation context,
* API operation response set within this class via (this.response)
* might end up being not documented API response for the executed operation.
*/
export default class extends middleware.apitest_ErrorMiddleware {
// This script gets executed if any error happens throughout the operation execution
public async handleError(error: Error): Promise<void> {
// Handle errors that may occur throughout operation execution
if (this.isInstanceOf.error.BusinessError(error)) {
this.response = new namespace_SomeOperationResponse();
this.response.status = 400;
this.response.body = this.factory.schema.v1.BadRequestError();
this.response.body.message = 'BadRequestError';
} else {
this.response = new namespace_AnotherOperationResponse();
this.response.status = 500;
this.response.body = this.factory.schema.v1.SystemError();
this.response.body.message = 'SystemError';
}
}
}
Operation error handling
Operation handleError()
method can be used to implement error handling logic for the errors that might occur within an
API operation's execution.
The handleError()
method is executed automatically if an error occurs, it gets the error that occurred as an argument.
The method will have access to operation modelled responses. The passed error can then be checked using isInstanceOf
utility and the operation response can be set accordingly.
handleError()
method on operation level is not implemented / did not set a proper response, then
ErrorMiddleware handleError()
will be called.See below example (ehns
is the name of the API namespace):
export default class extends operations.ehns_getPizza {
public async execute(): Promise<void> {
const log = this.util.log;
log.debug('ehns_getPizza.execute()');
// Execute some logic below that might result in an error
}
/**
* This function is automatically called when an error occurs within the execution flow
* of this operation ehns_getPizza @param error Operation execution error that occurred
*/
public async handleError(error: Error): Promise<void> {
const log = this.util.log;
log.info('ehns_getPizza.`handleError()`');
// Add Error handling logic below and set this.response that will be returned as operation ehns_getPizza response
if (this.isInstanceOf.error.GeneralError(error)) {
this.response.status = 500;
this.response.body = this.factory.schema.ehns.GeneralErrorSchema();
this.response.body.errorCode = 'GE101';
this.response.body.errorMessage = 'General Error occurred, original Error message: '
+ error.message;
}
if (this.isInstanceOf.error.ValidationError(error)) {
this.response.status = 400;
this.response.body = this.factory.schema.ehns.GeneralErrorSchema();
this.response.body.errorCode = 'VE101';
this.response.body.errorMessage = 'Validation Error occurred, original Error message: '
+ error.message;
}
if (this.isInstanceOf.error.BusinessError(error)) {
this.response.status = 400;
this.response.body = this.factory.schema.ehns.GeneralErrorSchema();
this.response.body.errorCode = 'BE101';
this.response.body.errorMessage = 'business error occurred, original Error message: '
+ error.errorMessage;
}
}
}