Error Handling¶
In large scale systems, error handling is an important aspect of web API design, as it helps ensure that the API is robust, reliable, and easy to use. Good error handling can help developers quickly diagnose and resolve issues, and can help ensure that the API remains available and responsive even in the face of errors.
ABP framework provides a built-in infrastructure and offers a standard model for handling exceptions.
-
Automatically handles all exceptions and sends a standard formatted error message to the client for an API/AJAX request.
-
Automatically hides internal infrastructure errors and returns a standard error message.
-
Provides an easy and configurable way to localize exception messages.
-
Automatically maps standard exceptions to HTTP status codes and provides a configurable option to map custom exceptions.
Automatic Exception Handling¶
AbpExceptionFilter
handles an exception if any of the following conditions are met:
- Exception is thrown by a controller action which returns an object result (not a view result).
- The request is an AJAX request (
X-Requested-With
HTTP header value isXMLHttpRequest
). - Client explicitly accepts the
application/json
content type (viaaccept
HTTP header).
If the exception is handled it's automatically logged and a formatted JSON message is returned to the client.
Error Message Format¶
Error Message is an instance of the RemoteServiceErrorResponse
class. The simplest error JSON has a message property as shown below:
{
"error": {
"message": "This topic is locked and can not add a new message"
}
}
There are optional fields those can be filled based upon the exception that has occurred.
Error Code¶
Error code is an optional and unique string value for the exception.
Thrown Exception
should implement the IHasErrorCode
interface to fill this field. Example JSON value:
{
"error": {
"code": "App:010042",
"message": "This topic is locked and can not add a new message"
}
}
Error code can also be used to localize the exception and customize the HTTP status code (see the related sections below).
Error Details¶
Error details in an optional field of the JSON error message. Thrown Exception
should implement the IHasErrorDetails
interface to fill this field. Example JSON value:
{
"error": {
"code": "App:010042",
"message": "This topic is locked and can not add a new message",
"details": "A more detailed info about the error..."
}
}
Validation Errors¶
validationErrors is a standard field that is filled if the thrown exception implements the IHasValidationErrors
interface.
{
"error": {
"code": "App:010046",
"message": "Your request is not valid, please correct and try again!",
"validationErrors": [{
"message": "Username should be minimum length of 3.",
"members": ["userName"]
},
{
"message": "Password is required",
"members": ["password"]
}]
}
}
AbpValidationException
implements the IHasValidationErrors
interface and it is automatically thrown by the framework when a request input is not valid. So, usually you don't need to deal with validation errors unless you have higly customised validation logic.
Example Error Response¶
{
"error": {
"code": "string",
"message": "string",
"details": "string",
"data": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"validationErrors": [{
"message": "string",
"members": ["string"]
},
"message": "string",
"members": ["string"]
}]
}
}
Log Level¶
Exceptions are logged with the Error
level by default. The Log level can be determined by the exception if it implements the IHasLogLevel
interface.
public class MyException : Exception, IHasLogLevel
{
public LogLevel LogLevel { get; set; } = LogLevel.Warning;
//...
}
Business Exceptions¶
The IBusinessException
interface is used to mark an exception as a business exception.
BusinessException
implements the IBusinessException
interface in addition to the IHasErrorCode
, IHasErrorDetails
and IHasLogLevel
interfaces. The default log level is Warning
Usually you have an error code related to a particular business exception.
For example:
throw new BusinessException(OdmsErrorCodes.InvalidFileNameError);
OdmsErrorCodes.InvalidFileNameError is just a const string
The following error code format is recommended:
<code-namespace>:<error-code>
For example:
Odms:00141
See Exception Handling in cross cutting concerns in the user documentation.
HTTP Status Code Mapping¶
ABP tries to automatically determine the most suitable HTTP status code for common exception types by following these rules:
- For the
AbpAuthorizationException
: - Returns
401
(unauthorized) if user has not logged in. - Returns
403
(forbidden) if user has logged in. - Returns
400
(bad request) for theAbpValidationException
. - Returns
404
(not found) for theEntityNotFoundException
. - Returns
403
(forbidden) for theIBusinessException
(andIUserFriendlyException
since it extends theIBusinessException
). - Returns
501
(not implemented) for theNotImplementedException
. - Returns
500
(internal server error) for other exceptions (those are assumed as infrastructure exceptions).
The IHttpExceptionStatusCodeFinder
is used to automatically determine the HTTP status code. The default implementation is the DefaultHttpExceptionStatusCodeFinder
class. It can be replaced or extended as needed.
Custom Mapping¶
Automatic HTTP status code determination can be overrided by custom mappings.
services.Configure<AbpExceptionHttpStatusCodeOptions>(options =>
{
options.Map("Odms:00141", HttpStatusCode.Conflict);
});