Exception Handling for specific condition - Best Practice [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have following code in DAO method :
public void someMethod() throws CustomException {
try {
... do something ...
}catch(Exception e) {
if(e.getCause() instanceOf org.hibernate.ConstraintViolationException && e.getMessage().contains("child record found")) {
throw new CustomException("Child records found.");
}else {
throw new CustomException("Unable to update.");
}
}
}
In service layer :
public void someMethod() throws CustomException {
dao.someMethod();
}
And in Controller :
public ResponseObject someMethod() {
ResponseObject response = new ResponseObject();
try {
service.someMethod();
response.setMessage("success");
}catch(CustomException e) {
response.setMessage(e.getMessage());
}
return response;
}
Am I going correctly as per BEST PRACTICES ?
What else I can do to make it proper ?
Any help appreciated!

A few things I noticed. First, use exceptions only for exceptional conditions. Put another way, exceptions should be the exception, not the norm. From what it looks like, "ConstraintViolationException" is something that is going to be expected a lot.
Exceptions make the code uglier, harder to debug, and reduce JVM optimizations that greatly speed up program execution.
Second, you should only use checked exceptions (exceptions that don't extend from RuntimeException) if the caller can be reasonable expected to recover. In your case, the caller doesn't do anything to recover except give the client an error message.
By throwing a checked exception, you force the caller to handle the exception in a catch clause or propagate it outwards. (Both are these pitfalls are detailed in Joshua Bloch's excellent book, "Effective Java".)
Third, in your exception handling, you try to parse the error message. This can be very problematic because third parties often change their error messages, because they
are not a part of the API. Once this happens, you're code is broken. Another minor problem in your exception handling is that tie your JPA implementation to hibernate. What if later you want to change to EclipseLink?
There is a way to address all these issues.
Get rid of the exception handling in your DAO.
Add the following method to your DAO:
boolean childRecordExists(Record record)
Then, in your controller, have something like:
if (service.childRecordExists()){
response.setMessage("Failed. A child record exists"); //a useful error message for the user, as you know *exactly* why failure happened
} else {
service.someMethod();
response.setMessage("Success");
}
You will need some sort of exceptionHandler in the controller. (If you're using Spring MVC, you can just add it as another method using the ExceptionHandler annotation.)
This would address things that are truly exceptions (things that are out of the ordinary for the everyday user experience, and things that the user can't fix.)

Related

Is there a good way to cancel/rollback an async realm transaction mid way through its logic?

I have been going over the realm documentation and found no feasible way of cancelling an asynchronous transaction from within the transaction "body" i.e. Realm.Transaction.execute()
So the only recourse I seem to have if I want to use the executeTransactionAsync() API's is to do something like:
realm.executeTransactionAsync(
new Realm.Transaction() {
#Override
public void execute(#NonNull Realm realm) {
// pretend we have some inter dependent database operations here
if (failureCondition) {
throw new Error("Failed transaction");
}
// and more here...
}
},
new Realm.Transaction.OnError() {
#Override
public void onError(#NonNull Throwable error) {
Log.e(LOG_TAG, error.getMessage());
}
}
);
Is there really no better way to do this? If re-ordering the operations such that a simple return would suffice and the transaction could be partially committed was an option that is obviously what I would do but what if it isn't.
Of course the above is technically functionally identical to just calling realm.cancelTransaction() in execute(), since it causes the attempt to commit the transaction that no-longer exists to throw an exception anyways. However, judging from the fact that the actual async transaction code behind this nice API doesn't check with realm.isInTransaction() before attempting to commit nor allows execute() to throw any checked exceptions neither approach seems to be something the designers even considered a valid use case.
I guess in the end I sort of answered myself, so perhaps the better question would be... is this a problem with the design of the API itself or am I just attempting to do something fundamentally wrong.

Good Practice : Exception Handling

I have 2 classes in my module where one of the class say Class A has methods which could throw InterruptedException, NoSuchElementException and another class say class B has methods which calls the method from class A.
Could someone please guide me with what is a good practice to implement exception handling? Shall it be CASE 1 or CASE 2 or any other way to do so.
CASE 1 ::
Class A
methodA1 throws InterruptedException, NoSuchElementException {...}
methodA2 throws InterruptedException, NoSuchElementException {...}
.
.
.
.
methodA10 throws InterruptedException, NoSuchElementException {...}
Class B
a = new A();
methodB1 {
try{
a.methodA1();
a.methodA2();
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
methodB2 {
try{
a.methodA9();
a.methodA10();
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
SCENARIO 2 ::
Class A
methodA1 {
try{
//perform actions
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
.
.
.
.
methodA10 {
try{
//perform actions
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
Class B
a = new A();
methodB1 {
a.methodA1();
a.methodA2();
}
methodB2 {
a.methodA1();
a.methodA2();
}
It really depends on what you need to achieve.
The situation might be flexible enough to allow you to handle exceptions as they arise within the specific module. For instance, you have some process which queues elements, an exception is thrown and in your exception handling code, you simply try again. The caller knows that when the method is called, something will be added but does not require to be informed of when/how.
On the other hand, the situation might require that you inform the caller immediately should something happen. Taking the above example, maybe the caller would need to know if the queueing was successful or not so that they could direct the user accordingly.
There are also scenarios where bubbling up the exception, although recommended, needs to be done in such a way that internal exceptions are not divulged to the caller since it could expose the internal structure of the module, which could be a security risk.
Usually, what one does is that, where necessary, exceptions are wrapped within custom exceptions. And if any errors occur, the custom exceptions are used to bubble up the error. It will then be up to the caller to decide what to do if/when an error occurs.
rethrowing or handling depends whether the caller can handle the exception reasonably.
E.g. if an UI triggers a calculation via a method chain, it might not be reasonable that somewhere in this chain the exception gets lost, as it would be of interest to present in the ui the exception to the user.
So it mostly depends on the context which scenario is preferable.
A rule of thumb is: However can handle the exception reasonably should do so
It depends on what you want to achieve by that and where you want to handle the exceptions. If you can handle the exception properly inside the methodA1() it'll be easier to use the method (no try-catch necessary around method calls)
If you can't handle the exception in the method itself (e.g. not enough information to handle the exception properly) and you can only handle it properly in methodB1 then you should use SCENARIO 2

Is "throws Throwable" good practice

In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."

Java, return new MyException: anti-pattern?

In my class I'm doing validation of custom data. Many conditions apply. Upon any failure, I want to throw a specific MyException. Throwing this MyException takes many common parameters, and one custom parameter (based upon the actual failure). So an actual throw takes many characters to write and destroys tidyness because of code duplication. Also I have to throw it too much times. I made up my mind to create a private method that prepares and returns a new instance of this MyException and takes the only custom data as parameter, so the code can be much cleaner.
private MyException createMyException(final CustomErrorData errorData)
{
... some info gathering, parameterizing, etc...
return new MyException(errorData);
}
...
So throwing a new MyException is much shorter:
throw createMyException(errorData);
My question is: what's the correct practice to prevent code duplication in this case? I may be overmistifying Exceptions.
An Exception factory - never seen it before but at least it sounds like a proper design.
I just worry - you seem to put quite a lot effort on designing an exception throwing framework: adding parameters, states, etc. to exceptions. Do you really encounter that many exceptional conditions in your code? Or do you throw exceptions where proper handling of expected conditions would?
Usually a thrown exception is "just for the logs". Something happened that shouldn't have happened in the current context. Something, the developers should know and correct in the next release. We shouldn't use exceptions to handle expected states.
So before investigating in brilliant exception creation code, double-check if it's worth the effort or if the design of your application is starting to get ... too creative.
If you have one general type of exception you will lose some of the advantages of OOP.
Instead of being able to have try-catch for specific exception types you will have to have a catch for your general exception and then continue processing based on some fields inside your MyException class.
You will have something like this:
try{
//code here
}
catch (MyException ex){
switch(ex.exceptionType){
case IOException: doSomething();break;
case ConnectionException:doSomethingElse();break;
default: //throw the exception outwards if you don't want to process it
}
}
When instead you should have something like
try{
//code here
}
catch (IOException ex){
doSomething();
}
catch (ConnectionException ex){
doSomethingElse();
}
which is more clear and more OOP.
Why you would place all your exceptions under a general type is something of a puzzle, it's like making all your objects to be instances of only one class, but you would require of them different behaviors based on some flags.
Imho your helper function is perfectly fine, i dont see another approach that would be preferable here..
I would throw the exception in the method, unless this confuses the compiler.
private void throwMyException(final CustomErrorData errorData) {
... some info gathering, parameterizing, etc...
throw new MyException(errorData);
}
throwMyException(errorData);
or
private MyException throwMyException(final CustomErrorData errorData) {
... some info gathering, parameterizing, etc...
throw new MyException(errorData);
}
throwMyException(errorData);
// or if the compiler complains
throw throwMyException(errorData);
I'd separate the two concerns. Your class knows how to info gather, but shouldn't have to know about the exception (the user of that info).
First define a method to create a CustomErrorData instance:
private CustomErrorData createCustomErrorData() {
// info gathering
return new CustomErrorData(something);
}
Then define a constructor for the exception that uses a CustomErrorData:
public MyException(CustomErrorData errorData) {
// save it as a field
}
then
throw new MyException(createCustomErrorData());
where you need it.
This also allows you to use CustomErrorData for something else, perhaps logging, displaying to the user, whatever.

Pluggable Error Handling Strategy [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have service object (Service A), that has some specific repetitive asynchronous task . This service object also has a supervising object (Service B). I want to handle most of the errors concerning the specific task in Service A and only inform Service B if it needs to take any additional measures (e.g. when Service A does not know how to handle the error).
Since Service A depends on external resources (e.g. network availabilty) there are many different exceptions, that can be thrown and I do not know all of them right now.
Because of that I would also like to have a pluggable eror-handling strategy inside Service A so that it can handle different exceptions differently. I would like to plug in those stratgies using my IoC container.
Example A:
Service A is supposed to download something every 30 sec. (polling), but the URL is malformed so a MalformedURLException is thrown. A looks up the error handling strategy for MalformedURLExcpetion and in this case the strategy will mean canceling the download and informing Service B (the supervisor) via a callback.
Example B:
Service A is supposed to download something, but the hostname cannot be resolved. Again an Exception is thrown (sorry don't know exact type now) and the corresponding strategy will be looked up: in this case the download should be stalled and retried at another time until a certain threshold is hit.
My problem now: How should I implement this dynamic lookup of error handling strategies and the strategies themselves? Is there a pattern for that?
Well, the easiest and straight forward solution would be tu use plain java try catchs, not that flexible, but often useful enough as error handling strategies does not change that often. Those exceptions you can not catch are declared on the method to may be thrown, and may be handled by your Object B.
If you wanna be more flexible. Create an interface for your service A with all the possible exceptions declared. Implement that interface with logic but without any error handling. Then you could create ErrorStrategy objects that implement the interface as well and delegate incoming calls to another implementation of that interface, BUT and this is the interesting part append some error handling strategy for one or more particular exceptions. Here is an example to make it more understandable.
public interface A {
void someMethod() throws IOException, MalformedURLException;
}
class AImpl implements A {
#Override
public void someMethod() throws IOException, MalformedURLException {
// here goes your business logic
}
}
class ErrorHandlerOne implements A {
#Override
public void someMethod() throws IOException {
try {
delegate.someMethod();
} catch (MalformedURLException e) {
// handle the exception
}
}
}
If you wanna be even more flexible, I would recommend to use AOP mechanisms instead of the simple delegation chain, that way you can easily plug-in and exchange your error handling strategies. If you use Spring and your Service A is a Spring-Bean you could easily use Springs build in AOP support. In that case the after throwing advice is what you looking for.
After throwing advice: Advice to be executed if a method exits by throwing an exception.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
#Aspect
public class AfterThrowingExample {
#AfterThrowing(
pointcut="com.xyz.myapp.A.someOperation()"
throwing="ex")
public void doRecoveryActions(IOException ex) {
// ...
}
}
Keep it simple and use plain exceptions.
They are already meant to implement different error handling strategies: you can catch different exception and act accordingly. You can implement your own error handling scheme as long as exceptions remain, well, exceptional. Otherwise if it's really control flow, you should think about it differently.
Here is one in pseudo-code:
CannotDownloadException. When the download is realy not possible. Fatal error.
RetryDownlaodException. When the download is momentary not possible. Can implement retry logic.
The names are not so good, but it illustrates the principle.
class ServiceB {
private serviceA serviceA;
public download( URL url ) throws CannotDownloadException
{
try
{
serviceA.download( url );
}
catch( RetryDownloadException ex )
{
// you could have here something more elaborated that would
// perform a retry strategy based on a configuration (e.g. the number of retry,
// or the interval between retry)
try
{
sleep( 10 sec );
serviceA.download( url );
}
catch( RetryDownloadException ex )
{
throw new CannotDownloadException();
}
}
}
}
class ServiceA {
public download( URL url ) throws DownloadException
{
try
{
if( ! url.isValid() )
throws new CannotDownloadException();
serviceA.download( url );
}
catch( ConnectionException ex )
{
throw new RetryDownloadException();
}
}
}
Try Observer pattern. In general, your ServiceA should have methods like addFirstTypeExceptionsListener (ServiceListener l) addSecondTypeExceptionsListener (ServiceListener l)
or addExceptionListener (ServiceListener l, ExceptionTypeEnum type).
Your ServiceB then should implement ServiceListener interface which will probably have method like handleException (Exception e);
If we abstract away from your question then it's a bad practice to use exceptions for flow control.

Categories

Resources