Using exception for communication - java

I have heard that one should not use exception for communication.
I have a scenario that I would like to discuss.
We have a rest controller that invokes a service that is responsible for fetching a product from the database. Currently if product can't be found we will get an exception (checked exception) productNotFoundException.
This exception goes all the way to the controller. In the controller we have a controller exception handler (controller advice) that takes care of the exceptions and returns 404.
I was told that if they are run on different threads then the whole application would crash and it would be better to deal with the exception directly. Currently a lot of methods are being called and all have throws prodNotfoundex.
Can some one explain why it would crash. My project is a spring boot project.
I was told to return an empty response to the controller instead of throwing an exception.

I'm not sure how it would crash your application, if you handle/catch the exception properly.
Regarding exceptions, it should be seen as an exceptional state -- that is not in the normal flow of actions. Eg. the FileNotFoundException is exceptional, because you wanted to open the file, but it's not there. You expected it to be there, but it wasn't.
If you search for a product, you don't expect it to be there in the general sense of "expecting to find a loaf in the grocery store". You searched for a bunch of keywords, and the search resulted an empty response/zero matches. It is not exceptional in your business logic.
On the other hand, when you click "order" on a product (say on the product page), and then the product is not found, it is "exceptional". You expected a product you found 2 minutes ago to be there, but it isn't any more.
Some links on Java Exception handling costs:
http://java-performance.info/throwing-an-exception-in-java-is-very-slow/
Is it expensive to use try-catch blocks even if an exception is never thrown?
How expensive are Exceptions
How slow are Java exceptions?
Decide it for yourself.

Related

Is it necessary to create user defined exceptions for each errors

I have created a spring application in which i have implemented log4j for logging. I have more than 300 errors(exceptions) in my application. I have created individual user defined exceptions for each error. Those classes doing nothing but returning error messages.
Reasons to create individual exceptions:
Developer should not missed out handling any error situations, when i create exception it will show error by default they have to handle to handle the situation.
While logging it will me more explanatory when i go through log if i create individual user defined exceptions for my error scenarios.
Now I am wondering:
Is it necessary to create individual user defined exceptions for each error scenario?
How most people handle errors and user defined exceptions in a better way?
I would nice if you could update your question with an example. I have built quite a few enterprise applications now and the motto I typically follow is make sure your exception type explains the proper category of the error and make sure your exception message properly explains what went wrong. You shouldn't create custom exceptions unless they are needed to properly classify the type of exception you are having. Here is a good example from mabbas:
When should we create our own java exception classes?
I think your question can't be answered in a good way; this is really about discussing different opinions. My opinion: as long as your individual exceptions are all well-defined (and not overlapping in their meaning); each one has good messages, and comes with the things you need to debug problems later on ... then: don't worry. That is what exceptions are meant to be used for. More (and custom) exception also allow for more specific and fine granular error handling.
But if using exceptions comes with severe cost (in our environment, we are sending exceptions from "independent" nodes A to node B ... and now, all of a sudden, you have to make sure that A, B are on matching code levels) things are different. Then you might consider very carefully, which architecture gives you the most "return on investment".
Seems like overkill to create 300 errors for 300 exceptions. What I did was create our own HttpErrorException class that contains the HTTP error we would like to return. Developers were advised to throw one of those when they encountered an exception or an error. If an exception bubbled up that was not one of the new HttpErrorExceptions, then a 500 is returned. We did not convert other exceptions into HTTP errors because I felt it is wrong to assume that each occurrence of a particular Exception will always map back to a particular HTTP error. The reason for this is because there are a lot of dependencies (other libraries we are using) and they might throw any type of exception which for any particular situation might not map back nicely to the HTTP error we had in mind. So I rather be explicit.
Here is a contrite example of a typical usage.
Account getAccount(String id){
Account a = null;
try{
a = accountRepo.findById(id);
catch(Exception e) {
String error = "Got exception while trying to get Account from db.";
logger.(error, e);
throw new HttpErrorException(500, error);
//or throw new HttpErrorException(HttpStatus.INTERNAL_SERVER_ERROR, error);
}
throw404IfNull(a);
return a;
}
The throwIf404IfNull is just a simple method we created to reduce if statements in our code. We have several of these methods and our code stays free of if statements that otherwise would get unit tested.
void throw404IfNull(Object obj){
if(obj == null) {
throw new HttpErrorException(400, "Object was not found");
}
}
We use Spring's exception handling capabilities to map all HttpErrorException's to a nice well formatted HTTP error with the error status that is in the exception.

Best practice on exception and error handling with Selenium and SerenityBDD (thucydides)

Actually I'm writing a bunch of tests but I'm not sure how I should handle exceptions/errors best.
There a different types of exceptions, e.g. AssertException if a result was not as expected using assertThat(..). This is O.K. and understandable.
But what if I have a FileNotFound / SOAPException / DOMException and so on...?
For example in my #BeforeStory method I create some testdata by reading testfiles and sending them to a webservice and there I could possibly get the above mentioned exceptions. I would like to present these errors by using an own error message also in the living documentation. But how should I manage this? Actually I'm thinking about two approaches:
1.) I catch the exception and throw my own new exception with an individual error message. The testexecution is aborted for the scenario and the exception is presented in the living documentation.
2.) I catch the exception, implement a string based return statement with the error message and use an assertThat(...) in my low-level specifications so I only should get AssertException in the end.
3.) ..?
Question: And advice or common best practices how to handle exceptions or errors with selenium/serenity ?
First of all, there is a good source of information for you theme - xUnit test patterns book.
Answering your question, the good approach is using 2 major groups of errors. The first one is AssertionException indicating a problem (bug) in application under test. The second one are all other exceptions indicating problems in test code itself, test execution env or application env, but not in application. Building your tests this way will help you finding and eliminating problems fast.
So generally you are on the right way with your first option. It's a good idea to collect some additional data (e.g. application/execution env) when exception occurs as well.

The use of checked exception for errors to be dealt with in web layer

I am having a hard time organizing how I should deal with errors that occur in the service layer. The reason for throwing that exception in this method is when the password provided is to weak or the confirmation id is wrong. The name of the exception is not settled yet though.
However, are checked exceptions to be avoided in a new application anyway? If so, how do I communicate errors like this to the caller? The caller in this scenario is the web layer which exposes a web service. I want to handle the error in the web layer and create a error message.
I have a method:
boolean confirmPasswordReset(int accountId, String confirmationId, String newPassword) throws ConstraintViolation;
And this is the exception class:
public class ConstraintViolation extends Exception {
public ConstraintViolation(String message) {
super(message);
}
}
From reading this article it looks like it should be right:
http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html
Contingency
Is considered to be: A part of the design
Is expected to happen: Regularly but rarely
Who cares about it: The upstream code that invokes the method Examples: Alternative return modes
Best Mapping: A checked exception
I try to use checked exceptions as little as possible. I think using a runtime exception and documenting it clearly is enough.
From your case, you seem to be the one designing and controlling the web layer. In that case, you already know what runtime exceptions your service layer throws and how to handle them. You don't need to be told by the compiler.
I would only use a checked exception if the exception is recoverable, and the client of the code is external where I have to force it to handle the exception. Even then, the result will most likely be one more empty catch block.
Here you can find a good discussion of the pro's and con's of both approaches.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
What I think is important (similiar to the author of article above) is that you choose which way to go (checked or unchecked) and then stay consistent. Otherwise you'll end up with a messy codebase and will likely suffer from the downsides of both approaches.

what is preferred approach to return business validation results in business layer

Let's assume we have a client application (either web or standalone) which uses kind of business layer (EJB, Spring services etc). Let's say user wants to execute some business logic (e.g. create something). This operation has some preconditions like data format, existing of other objects in DB, permissions etc. Now what is the best design of this business logic layer, I mean how to return validation errors, indicate success, return unexpected error etc?
Ways I know:
1)
for validation errors return e.g. OperationResult object having status and list of violations,
for success: OperationResult with status=success and empty errors list,
for unexpected errors throw runtime exception
2)
for validation errors throw ValidationException (runitme or checked?) having list of violations
for success: void or created entity if required
for unexpected errors throw runtime exception
There are two basic ways I know but every time I start writing I have hard time to get it right.
I have an aversion for the validation exception method, after all there is nothing exceptional in a validation error, so I find it hard to justify to use an exception for that. So on a theoretical basis the only valid option is the first one.
Having said that, although it depends on what validation framework you're using*, but it's usually much easier to code the exception version.
Whether your validation exception (if you're using one) should be checked or not opens up another can of worms, some people are very much against checked exceptions in general, others will say the exact opposite. For my two pennies worth I believe that runtime exceptions should be reserved for coding errors and an "expected" exception should be checked, whenever that's possible. But I have to stress that this is just personal preference on my behalf.
*If you have multiple validators that will all have to be run in a validation phase, exceptions are not very effective. If you intend to stop at the first failed validation step, exceptions are easier to implement and probably more readable.

Exception Handling in a Java Web Application

I am developing a medium size Java Web Application with Struts as MVC framework and simple JDBC at Data Access Layer. I have been searching for exception handling best practices in such an application. I have found several articles, some of them being contradictory, only making me more confused rather than making things clear and simple. Some say it is better to reuse existing exceptions instead of defining application specific exceptions, others present a huge hierarchy of application specific exceptions for every minor trouble that may occur in the system. Some say it is better not to handle exceptions at Data Access Layer and delegate them to the Service Layer, others say Data Access Layer exceptions should be caught locally since delegating them to Service Layer would violate the abstraction between the two layers. And so on.
I would highly appreciate if you let me know of links/names to articles/books that present solid solutions which have worked for you in such a scenario. The solution should clear at least the following points with justifications:
Where the SQLExceptions be caught?
Where exceptions should be logged?
Should unchecked exceptions be logged?
Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
How checked exceptions be handled, which of them to be shown to the user and how?
How should a global exception handler page be used?
How should struts ActionErrors be used in this context?
Thanks
1: Where the SQLExceptions be caught?
In DAO classes in data access layer. You can if necessary wrap it with a custom DAO exception. This DAO exception in turn needs to be handled further as checked exception.
2: Where exceptions should be logged?
At the moment when you're about to throw them or to pass through the messaging framework.
3: Should unchecked exceptions be logged?
They should certainly be logged. They should namely not occur in real world, because those are sign of a fault in the code logic (i.e. developer fault) which needs to be bugfixed asap. They should be thrown all the way up to the container and let the container handle them with an <error-page> in web.xml. To log (and eventually mail) them, use a Filter which listens on the error page.
4: Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
They should not occur at all.
5: How checked exceptions be handled, which of them to be shown to the user and how?
If they are result of errorneous user input (e.g. not a number, bad email, constraint violation, etc), show them in the same form to the user. Otherwise (e.g. DB down, DAO exception and so on) either throw it all the way up to the error page, or display the error with a message to try again later.
6: How should a global exception handler page be used?
At least in an user-friendly manner. Thus, in the same layout, with some introductory "sorry" and if necessary with some error details and an email address so that the user can contact for the case that.
7: How should struts ActionErrors be used in this context?
Show them in same form to the user.
If you can't recover from an exception, then you should let it flow out of your code (often by making it unchecked, or wrapping it in an unchecked exception). If they remain checked, you have to cater for them at each level of your code, and consequently at every abstraction layer. SQLExceptions would normally fall into this category (you'll have to wrap them since they're checked).
For these exceptions, I normally log at the highest level, but present a page to the users simply detailing that something has gone wrong. Normally my users aren't interested in stack traces. But I usually offer them a page to let them describe what they were doing at the time, and the logged exception ties back to this submission via a unique id (recorded in the form and in the log file with the exception). That allows me to tie back users' actions to the resulting exception.
The above assumes that you can't recover from SQLExceptions, and if the database is down, then you can't do something meaningful. There are exceptions to this, of course. You may find that you're talking to multiple systems, and one being down doesn't mean you can't continue in some fashion (e.g. the Amazon home page reportedly relies on 100 services, and needs to run regardless of some of these being down).
I would expect declared exceptions to be at the same level of abstraction as the interface/methods defining them. e.g. a TradeStore would be declared to throw a TradeException, not a SQLException (since methods of storing a trade are an implementation of TradeStore - you could store in a relational db, a JavaSpace etc.).
As a warning, when displaying lower level error messages to users, make sure they're sanitized of system information. This is an area where many security exploits originate. Log them with full information, but only display a more general error message to the user.

Categories

Resources