Reputation: 176
I’m consuming an external SOAP service in my Spring app. The SOAP service can throw an Exception while connecting so I catch that in a try catch block:
try {
response = soapService.callService(request);
} catch (Exception e){
throw SoapServiceException("explaining",e);
}
if (BAD_STATUS_CODE.equals(response.getStatusCode()) {
throw CustomException("explaining", e);
}
return response;
As you can notice, I also want to throw an exception when response is not what caller would expect, maybe for example because valid request format but values not found in soap service.
Is this a good practice? I'm trying to prevent wrapping the response object in another object that keep the error codes. I think it would be nice if service caller handles the exceptional cases like soap exception or the response exception. Thanks for your advice.
Upvotes: 3
Views: 1106
Reputation: 1
[HttpDelete]
[Route("api/employee/delete")]
public void Delete(int Id)
{
using (EmployeeDBEntities db = new EmployeeDBEntities())
{
try
{
Employee emp = db.Employees.FirstOrDefault(e => e.EmpId == Id);
db.Employees.Remove(emp);
db.SaveChanges();
}
catch (Exception ex)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(ex.Message)
});
}
}
}
Upvotes: 0
Reputation: 4000
Exception are a feature of the java programming language but are not mandatory to be used. Well you may have to catch the existing ones, but you don't have to raise new one.
This is a design decision for your application/framework/library. It is much better if the way to handle error in general is consistant accross the whole codebase. There isn't a better, universal way. It is a collective choice and also depend of the general expected behavior of your program.
A simple design
A "naive" or at least simple implementation typically would raise exception for many unsupported cases as this is an easy way to interrupt the execution, get a log of the error and an easy way to investigate.
In that way of seeing things, it isn't necessarily worth to have checked exception. Your exceptions can derive from RuntimeException, you don't need to declare them and simply raise them when there an issue.
The drawback of such design is that developpers will likely raise exception in many cases and that most these "exceptional" cases are actually common case in your application. A file is not found ? Well that's common. The network isn't available ? That's to be expected. The service didn't return what you do expect ? That can happen more often than you think...
At least in our production where we have thing like thousand of machines and hundred thousand of TPS everything will happen.
Toward a more robust implementation
So typically you'll separate what you'll consider to be something that you expect to happen and have to deal with (like a timeout for a network request or the DB being temporarilly unvalaible) or what shall never happen (a file part of your artifact distribution missing) or invalid parameters provided to a function (a code bug).
You'll keep exception for what is truely exceptionnal, and typically make them RuntimeException/unchecked because there nothing to be done. You just want such bugs to be logged and repported.
For all the rest, there may be exception in the middle but not globally. You want to deal with them and consider them as normal behavior.
In that case, the choice is your depending of the design.
But typically if I have to act and proceed normally when that occurs, I prefer as well to not have an exception. Typically for a network request, I would consider the Time Out to be actually be a valid response and returned as this to be part of the values I model in my business domain.
To have the Error and errors code part of my data domain allow me to accumulate/aggregate errors and to fine tune how I react to them. An exception on the opposite is more an all or nothing.
This allows for more flexibility on how functionnally I choose to react... Like I performed 10 requests, one time out, on returned an error, I don't want exceptions. I want the results and a "merge" strategy that depend of the functional aspects of my application.
In your example of BadStatus, I would consider it as an exception if that 's an error code I get because I provided invalid inputs (a bug in my code). But if that's because there no network or because there was an external failure, that expected behavior for me, so I would not throw.
That's my design choice, that's the teams I have been working with design choice. This doesn't has to be the universal choice. Just be sure you all agree on how to deal with such case and it match your overall software design
Checked exceptions
They force you do deal with it, and this can be a bless or a curse depending of the context.
This is a choice that you have in your design.
Do you only throw exception in exceptional cases that should not happen and use it as bug detection mechanism ? Then I think they are useless and when I use this strategy I wrap them in a derivate of RuntimeException to simplify my code and in a few key areas of my code I have generic catch all mechanisms that can be seen as framework lvl so I ensure I always return a proper response (even if that one with an error) and then I can centralize the loggging.
But again if you think the client shall alway deal with it, use the checked exception. The problem with that is that most often the caller cannot do anything directly, he may need to wrap into many intermediate just to forward it or have an handless list of checked exceptions.
So I am not that fond of them. But again that a design decision for you and the team.
Upvotes: 2
Reputation: 1317
Throwing exceptions in your code when the behaviour is unexpected is absolutely fine. Just be sure to mark your method
void testMethod() throws CustomException, CustomException2, ..
so that the caller of the method knows that there is a chance that an exception can be thrown. Uncaught exceptions will cause your program to terminate so be sure to catch, and handle appropriately.
Upvotes: 0
Reputation: 379
In all projects that I've been working we used exactlly as you, we throw an exception instead of wrapp this in any response object. Looks good for me.
Upvotes: -1