Use Java exceptions internally for REST API user errors? - api

We have a REST API that works great. We're refactoring and deciding how to internally handle errors by the users of our API.
For example the user needs to specify the "movie" url parameter which should take the value of "1984", "Crash", or "Avatar". First we check to see if it has a valid value.
What would be the best approach if the movie parameter is invalid?
return null from one of the internal methods and check for the null in the main API call method
throw an exception from the internal method and catch exceptions in the main API method
I think it would make our code more readable and elegant to use exceptions. However, we're reluctant because we'd be potentially throwing many exceptions because of user API input errors, our code could be perfect. This doesn't seem to be the proper use of exceptions. If there are heavy performance penalties with exceptions, which would make sense with stack traces needing to be collected, etc., then we're unnecessarily spending resources when all we need to do is tell the user the parameter is wrong.
These are REST API methods, so we're not propogating the exceptions to the users of the API, nor would we want to even if possible.
So what's the best practice here? Use ugly nulls or use java's exception mechanism?

Neither.
The key is that passing a bad parameter isn't that exceptional a condition. Exceptions are thrown for exceptional circumstances. (That's the reason to not use them here, not the performance.)
You should be using something like Spring's DataValidation API for binding parameters that are passed in.
A client of a REST API should not be receiving null or exceptions. They should get an error message that gives them an idea of what's going on without exposing those details. "Sorry, we couldn't find that movie" or null? Go with the first, hands down.

If a invalid request came in (e.g. validation error) you should show 400 status code (bad request).
Internally I would also create an exception hierachy which maps to the HTTP Rest domain (see status codes for error cases).
Examples (simplified and being unchecked exceptions):
class RESTBaseException extends RuntimeException{
int statusCode;
public RESTBaseException(int statusCode){ this.statusCode=statusCode; }
//if no statusCode passed we fallback to very broad 500 server error.
public RESTBaseException(){ this.statusCode=500; }
}
class RESTValidationException extends RESTBaseException{
RESTValidationException(){
super(404);
}
}
you can extend above examples by also passing error messages to constructor to make client even more happy.
Later on you should catch these exceptions with a dedicated exception handler in your servlet handler chain (mapping status code to servlet response). For instance in spring mvc there are nice exception-handling solutions for that.
Usually I don't like to create a deep custom exception hierachies but I think for REST api layers they are OK (because the status codes are propagated later).

I will assume that you are doing input validation here and in this case, your database will do a query for a safe string and it won't find the record since it don't exist in your database, ok?
If you are using any MVC framework the Model should throw already a RecordNotFound exception no?
If you are always expecting to find a value then throw the exception if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the application logic then return a null.
More important: What do you do in other places of the code? Consistency is important.

Related

Handing unauthorized requests in WCF?

We have an WCF service, using webhttp binding. Users get authenticated, and then a method is called. In the method, we check a variety of settings associated with the user and some information specific to the request before knowing if the user is authorized to make the call.
Since this is WCF, I think I should be throwing a FaultException of some sort, but it's not clear if there is best practices.
My thoughts are that once I know what exception I will be throwing, I'd add a IErrorHandler which would set the headers correctly to 403.
Two questions:
1) Is there a standard FaultException for unauthorized requests? i.e. the equivalent of the http status code of 403?
2) Should I be able to handle the exceptions that I'll be throwing and change the response code to 403? Will I be able to pass through a custom error message? I've seen some posts that setting headers using the operation context in a catch does not get propagated to the client.
Ideally I'd be able to set the status to 403 with additional information like "You must be part of the administrators group to add a user"
Because you're using webhttp binding, traditional WCF fault management is not pertinent here and it's better to use WebFaultException and WebFaultException<>.
Public string MyOperation()
// Operation logic
// ...
throw new WebFaultException<string>("You must be part of the administrators group to add a user", HttpStatusCode.Forbidden);
}
As you think, it's very important to use standard HTTP status codes when developping an HTTP (REST-like) service.
It's been my experience that throwing fault exceptions, at least with wshttpbinding and basichttpbinding, can cause your web service to fail, so I don't recommend that approach.
If you want to send a message back to unauthorized users, just send an HTML response, setting the status to any one of the 400 responses that seem appropriate.
But from experience, fault exceptions, even if they're a controlled response to user actions and not from an actual processing error, will cause your web service to fail. I think they should be reserved genuine processing exceptions.
I went ahead and derived custom exceptions from FaultException, and then added an IErrorHandler to set the appropriate headers.
This seemed to be the best of both worlds. The code only throws exceptions derived from ones used in WCF, and all the handling specific to http binding is done via an IErrorHandler outside the business logic.

WCF: use or not to use exception from service to client in production? any alternative?

I am thinking in use some exceptions to from service to client.
I am thinking for example in this case. The client try to insert a register in the database. This register has a value for e filed that exists in the database, and how it has a unique constraint, when I do the savechanges I get an updateException.
I am thinking to use exceptions (faultException) to warn to client of the error, and use a custom class to send to the client the actual data of the register, so in this way the client does not to make other query for the register.
However, in this link, it says that exceptions only should be used in development, no in production, so, without exceptions, how could I do what I want to do?
Perhaps I could use a custom class, that have one list property for each type of entities, and a property bool, that indicates if the operation is right or wrong, other property with an arbitrary code to indicate the type of error... etc. This is a good alternative?
In summary, really is better avoid exceptions in production? how I could communicate to the client errors from the service?
You have 2 options:
Throw exceptions and return WCF faults
Attach error information to you return objects
I personally favour throwing exceptions and returning WCF faults. I dont like the idea of attaching error information to return objects, I feel it violoates object oriented principals. For example a field called 'ErrorCode' has no place on a 'CustomerAddress' object.
I believe that if exceptional circustances arise, then an exception should be thrown. This will also simplfy your code as you wont have to wrap everything in try catch blocks in order to attach error information to your return object. Although you may want to catch unexpected exceptions and then throw a more appropriate exception with a more useful message.

to service response context or not

when calling a state changing service e.g.
void SaveCustomer(Customer customer)
the following may happen
the parameters are invalid
an exception occurs
authorisation is not successful
a business rule(s) is violated
everything is ok
For conditions 1-3 I think the service should return an appropriate exception
For #4 I also think the service should return an exception but some believe it should return an object that reflects the success or otherwise of the call (a response object).
In our case a business rule violation is an opportunity for an end user to choose an alternative action. I think a custom exception that lists error codes can be parsed by a client and localised. A response object can do the same but in a more strongly typed way.
With a response object we need to cater for a path back up the stack to the service (if(ok) etc) and we can't rely on an exception unwiniding a transaction.
Is either of these options an anti-pattern?
There is also third approach not mentioned by your listing. The approach is called expected exception. Request-response operations in web services offers definition of three types of messages:
Input = request. Can be defined only once for each operation.
Output = successful response. Can be defined only once for each operation.
Fault = expected unsuccessful response. You can have zero or more faults defined for each operation.
When using faults you tell client that the operation can fail due to some well defined reason. For example incomplete customer definition and client can handle this fault in different way than common unexpected SOAP fault.
In WCF expected faults are handled through FaultContract and generic FaultException<>. Check this article and its subarticles for introduction to fault handling.
The implementation of error handling is mostly up to you. Returning custom object is especially helpful in complex scenarios where the operation can succeed only partially and you must report both success and parts which failed.

WCF Response Class Best Practices

I'm not sure if there's a best practice for Response Message in WCF. Could anyone please guide me to right direction please?
I've a BlaResponse Object with following attributes:
1. dateTime
2. sucessfailureMessage.
is there anything else I need to add e.g. number of errors, details of errors. Number of success correlationID etc etc?
Thank you in advance.
Why do you have such attributes. You must have some real requirement for introducing these parameters in your response - for example response grouping both successful and failed operations. If your response is just for single operation you should get rid of that and use exceptions for propagating faults.
WCF has very big support for typed exceptions - FaultContracts. You can create special FaultContract type for any expected exception and throw it with typed FaultException. Client can catch each expected exception separately and handle it.
It is generally considered good practice to hide technical details of errors, or any information that discloses details about the server / architecture from the clients (unless you are debugging of course), as this might compromise your security.
It really depends what you are doing, so I don't think I can say what additional info you might need without more information about your implementation. Even the standard Fault Contract is pretty much just a wrapper for your own custom data.

WCF - Faults / Exceptions versus Messages

We're currently having a debate whether it's better to throw faults over a WCF channel, versus passing a message indicating the status or the response from a service.
Faults come with built-in support from WCF where by you can use the built-in error handlers and react accordingly. This, however, carries overhead as throwing exceptions in .NET can be quite costly.
Messages can contain the necessary information to determine what happened with your service call without the overhead of throwing an exception. It does however need several lines of repetitive code to analyze the message and determine actions following its contents.
We took a stab at creating a generic message object we could utilize in our services, and this is what we came up with:
public class ReturnItemDTO<T>
{
[DataMember]
public bool Success { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
[DataMember]
public T Item { get; set; }
}
If all my service calls return this item, I can consistently check the "Success" property to determine if all went well. I then have an error message string in the event indicating something went wrong, and a generic item containing a Dto if needed.
The exception information will have to be logged away to a central logging service and not passed back from the service.
Thoughts? Comments? Ideas? Suggestions?
Some further clarification on my question
An issue I'm having with fault contracts is communicating business rules.
Like, if someone logs in, and their account is locked, how do I communicate that? Their login obviously fails, but it fails due to the reason "Account Locked".
So do I:
A) use a boolean, throw Fault with message account locked
B) return AuthenticatedDTO with relevant information
This however carries overhead as throwing exceptions in .NET can be quite costly.
You're serializing and de-serializing objects to XML and sending them over a slow network.. the overhead from throwing an exception is negligable compared to that.
I usually stick to throwing exceptions, since they clearly communicate something went wrong and all webservice toolkits have a good way of handling them.
In your sample I would throw an UnauthorizedAccessException with the message "Account Locked".
Clarification: The .NET wcf services translate exceptions to FaultContracts by default, but you can change this behaviour. MSDN:Specifying and Handling Faults in Contracts and Services
If you think about calling the service like calling any other method, it may help put things into perspective. Imagine if every method you called returned a status, and you it was up to you to check whether it was true or false. It would get quite tedious.
result = CallMethod();
if (!result.Success) handleError();
result = CallAnotherMethod();
if (!result.Success) handleError();
result = NotAgain();
if (!result.Success) handleError();
This is one of the strong points of a structured error handling system, is that you can separate your actual logic from your error handling. You don't have to keep checking, you know it was a success if no exception was thrown.
try
{
CallMethod();
CallAnotherMethod();
NotAgain();
}
catch (Exception e)
{
handleError();
}
At the same time, by returning a result you're putting more responsibility on the client. You may well know to check for errors in the result object, but John Doe comes in and just starts calling away to your service, oblivious that anything is wrong because an exception is not thrown. This is another great strength of exceptions is that they give us a good slap in the face when something is wrong and needs to be taken care of.
I would seriously consider using the FaultContract and FaultException objects to get around this. This will allow you to pass meaningful error messages back to the client, but only when a fault condition occurs.
Unfortunately, I'm in a training course at the moment, so can't write up a full answer, but as luck would have it I'm learning about exception management in WCF applications. I'll post back tonight with more information. (Sorry it's a feeble answer)