In one of my previous posts I described how to create custom error handler for the RESTful endpoints in WCF service. It uses simple idea: store exception message into Status Description field, so e.g. if with standard handler you got something like this:
HTTP/1.1 500 Internal Server Error
Then in with custom error handler you will get the following:
HTTP/1.1 500 InternalServerError: Customer Id can’t be empty
So when such exception will be handled on the client side you will have its actual reason. It was done using the following code in custom error handler:
And it works. But recently I found one problem with this approach (quite predictable I would say): with using HTTPS you may get the following exceptions from the server:
The server committed a protocol violation
Because of some reason for simple HTTP protocol it was not thrown (however for HTTPS it also was not regular). Anyway this is a problem which we should address and found more correct way to handle exceptions on the client side.
First of all I turned off my custom handler and ensure that problem is not reproducible without it. Of course I got only generic “Internal Server Error” again. After it I checked from where this exception is thrown on the client (remember that we are talking about RESTful endpoints – which use WebHttpBehavior. JSON and SOAP endpoints are out of scope in this post. I will describe them in the future posts). It is thrown in the WebFaultClientMessageInspector internal class which implements IClientMessageInspector interface:
(Another method of the interface BeforeSendRequest(…) just returns null).
Now it became clear why we always got generic “Internal Server Error” exception for the RESTful endpoints. Also it became clear why we can’t use FaultExceptions<FaultContract> for the RESTful service – it is ignored on client side and CommunicationException is thrown instead.
How to solve this problem? The answer is obvious: create custom implementation IClientMessageInspector and use it on client. Remember that it is called on the client side (on server side there is equivalent IDispatchMessageInspector). But how to send error message to the client? I used custom HTTP header with base64 encoded string. Algorithm is the following:
- On the server side register and use custom error handler as shown in the previous article.
- Instead of modifying of StatusDescription field we store error message in custom HTTP header (preliminary converted to base64 string)
- On the client side we use custom message inspector – check the custom HTTP header and if it is not empty, decode it and rethrow exception with initial error message
- As result we will have the exception with the same error message as initially thrown from the server
Now lets check the code. First of all we need to modify our custom error handler on the server:
Now we need to catch it on the client. Create custom client message inspector:
The only remaining way is to register it on the client side. In order to do it we need to create custom inheritor of the WebHttpBehavior class and register our own message dispatcher instead of standard one:
Now in order to register it via config file of our client application we need to create custom extension element:
After these manipulations we can register and use our custom message dispatcher in client’s config file:
Now on client we will get server’s error message without problems with protocol violation.