Diagnostics
Bulletcode.NET contains built-in mechanism for error handling and logging. To enable it, call the UseErrorHandling() extension method of the IApplicationBuilder:
app.UseErrorHandling( app.Environment );
The /Error route is used as the unhandled exception handler, and the /Error/{0} route is used to handle error status codes. Both routes are handled by the built-in ErrorController.
In development mode, the unhandled exception route is not registered, and the default ASP.NET Core developer exception page is used instead.
The ErrorController creates a ErrorResult model containing error details and passes it to the Error view. The application should implement the Shared/Error.cshtml view.
The ErrorResult contains the following information:
Reason— a string identifying the reason of the error; theErrorReasonstatic class contains commonly used reasons.Message— a human-readable message describing the error.Details— details of the error; this property is available for API validation errors and unhandled exceptions (in development mode only).
In ClientView mode, a client-side view can be used to render server errors. See Rendering a client view for more information.
API Errors
API error handling is automatically configured when the AddCoreMvcServices() extension method of the IMvcBuilder is called. This registers a handler for invalid model state errors which produces an ErrorResult JSON response.
The ValidationProblem() method of the BaseApiController is overridden to also produce an ErrorResult JSON response instead of the standard ProblemDetails response.
For API controllers, the automatic creation of a ProblemDetails response for error status codes is disabled. The ErrorController is used to produce an ErrorResult JSON response.
In development mode, a custom IDeveloperPageExceptionFilter is registered, which returns an ErrorResult JSON response containing the full exception details instead of the default ASP.NET Core developer exception page when an API request is detected.
The API controller can also explicitly return an error result when some business logic error occurs, for example:
return BadRequest( new ErrorResult( ErrorReason.BadRequest, "Invalid email or password" ) );
A service can also trigger an error response by throwing the ApiErrorException, for example:
throw new ApiErrorException( ErrorReason.BadRequest, "Invalid email or password" );
Other exceptions by default produce an UnexpectedError with status code 500. The application can register one or more API error filters which convert various types of exceptions to more specific API errors. The IApiErrorFilter interface contains one method, OnException(). It receives a context argument containing the exception object. The filter can set the result object and an optional status code (which defaults to 400 if not specified), for example:
class MyErrorFilter : IApiErrorFilter
{
public OnException( ApiErrorContext context )
{
if ( context.Exception is MyException )
context.Result = new ErrorResult( ErrorReason.BadRequest, "Custom error message" );
}
}
Exception filters can be registered using AddCoreMvcServices():
services
.AddControllersWithViews()
.AddCoreMvcServices( environment, options => {
options.ApiErrorFilters.Add( new MyErrorFilter() );
} );
The IApiClient service tries to deserialize the ErrorResult JSON response when a request fails, and throws an ErrorResultException containing the information about the error. See API Client for more information.
Request Logging
When the UseErrorHandling() method is called, a middleware is registered which logs all 4xx responses as warnings. The error message or details are included if available.
The UseDiagnosticTags() method can be used to register a middleware which adds the remote IP address, user’s authentication type, ID and name to the diagnostic activity tags. Those tags are then included in the scope data of the logged events. See Logging for more information.