The client can use HTTP methods to perform read/write operations. .NET uses HttpRequestMessage and HttpResponseMessage to manage messaging to and from Web API and, on the other hand, of Node JS has a lot of options to deal with Http requests like Express, Sails, actionHero, Server, among other possibilities (you can check it here). For the Node, we gonna use the Express lib to handle the requests. This lib has req and res methods to manage the messages to and from server.
Since the HttpStatusCode (.NET) or res (Express) are pre-configured for default HTTP error codes like 500, 403, etc, it’s a challenge to respond with the exact exception that occurred on the server-side while processing requests. This challenge can be addressed by implementing Exception filter on our web server. In This article, we are going to replace the default http error body by a JSON response containing details related to error that happened. In fact, this is a nice approach allowing us to get better control of the behavior of our server.
The following diagram gives an idea of the exception filter process.The exception filter is the main part and will catch all errors that happens inside an action while it’s executing.
When the ApiController (the main part for the Web API) or Node Controller executes an action, they will load the ExceptionFilter if an exception occurs during the execution. In this case of Web API, The ExceptionFilter implements IHttpActionResult. Already for the Express, we need to define a middleware to be the error handling function.
Without further ado, let’s built it! :D
We’ll use two approaches for the error handle:
1 - Invalid route
2 - Internal server issue
For the first case, we can make a Express middleware that will trigger when a invalid route is received as the following:
This middleware will handle every request that reaches him, which means that no predefined route was able to handle the request.
Inside of the “route handler”, we have a Error object that will assign a status and send it to a next main error handler when the user tries to request an invalid route — a not found route defined by 404 http status. The next method will pass our error along to a main error handler defined below:
The Figure 2 explains us how is the internal behavior of exception filter in the Express:
The main handler will deal with errors that belong to second case, like database errors or validation errors for instance. When a database interaction goes wrong, it will throw an error, then the middleware above will catch and assign it a status together with the message from the error and return it as JSON.
Let’s take a look in the following use case where we’re accessing a database:
Here, we would have a “not found” error when ‘idColor’ isn’t found. So, the next statement passes the control to the next function in the middleware stack. At the same time, we have an object containing the error details — a 404 status with the message ‘The record was not found’.
Finally, into res method on the “internal errors handler”, we would send the response to the client that, in this case, is a 404 error. Furthermore, we can have other kinds of error like a 500 or 403 status inside this middleware and typically them would also have a message property. The main idea is whatever error, they always will flow through this “internal error handler”.
For .NET we have the ExceptionFilter that takes all exceptions and then passes it to the Exception Filter attribute. We have the liberty to implement the Exception filter as per the logical requirements of our application. When the ApiController executes an action from the class, it loads the ExceptionFilterResult if things goes wrong. The .NET environment uses HttpRequestMessage and HttpResponseMessage to manage messages that flow through the server setting up the HttpStatusCode value.
The first step to do it is add a new folder with the name “CustomHttpFilter”. Inside this folder add a new class file with the following code:
The code above contains class derived from the Exception base class as well as the constructor for exception message.
Now, let’s create in the CustomHttpFilter folder a new class file named “ProcessExceptionFilter” as follows:
The ProcessExceptionFilter is derived from ExceptionFilterAtribute base class that runs an abstract filter asynchronously after an action has thrown an Exception. This will allows us to implement a custom exception filter in our Web API. Here, the focus is on the HttpActionExecutedContext object that is responsible for runtime exceptions check.That object reads the exception message and finally, set the message property.
To handle exceptions, we need to register a custom exception filter in our project. Let’s open WebApiConfig.cs file and add the exception filter in HttpConfiguration:
And then, In the Controllers folder, let’s add a new validation rule using try/catch statements (the controller used bellow is only an example to use) :
In the controller code above, we simulated a scenario of error, making item null. We could use a web project based on jQuery, Vue or Angular for test and handle our exceptions, but to simplify, I’m going to use the Postman to do it. As expected, when we call “localhost:2990/api/deletecolor/1” route, the ProcessExceptionFilter returned the error message and 500 status as Figure 3 shows.
That test will works the same for both cases either using .NET or Express example.
How we’ve seen, a custom exception filters acts as a value addition in our Web API. This article approached only Node and .NET technologies, but it can be applied to various languages like PHP, Java, Python, and so on. The customized exception filter allow us in a simple way send custom messages to the client application when errors occurs.
How we’ve seen, a custom exception filters acts as a value addition in our Web API. This article approached only Node and .NET technologies, but it can be applied to various languages like PHP, Java, Python, and so on. The customized exception filter provides a simple way to send custom messages to the client application when errors occurs and at the same time, allow us to identify quickly what in fact happened.