Springboot provides #ControllerAdvice to handle exceptions in controllers.
But in service layer, there is no such annotations.
I've learned about spring-aop uses #AfterThrowing track exception, but #AfterThrowing cannot catch exceptions.
Another solution is to catch all exceptions with #Around, but it is kind of wastful to just log exceptions.
So, how to handle exceptions in service layer graceful?
The general idea is to let exceptions bubble up to controllers where they can be taken care of by components annotated with #ControllerAdvice or #RestControllerAdvice.
In order to achieve this you have to throw unchecked exceptions in your application when needed, i.e. if business validations fail. This also means that you have to catch any checked exceptions that might be thrown by third party dependencies and re-throw them as unchecked exceptions in your application, i.e. the infamous IOException and dozens of its sub-variants.
Apart from the above there's usually no need to handle exceptions in the #Service or the #Repository layer. There's rarely a reason to introduce aspects for any exception handling related logic either.
Related
Im thinking of creating custom exceptions. So that all types of camel route exceptions are to be handled in Processor files. Could someone please answer what are the camel exceptions that might occur in camel routes, so that i can create custom exception hierarchy based my requirement..?
Any kind of exception can be thrown during routing, eg a java.lang.Throwable as the super type.
If you do some IO work then IOException can be thrown, if you do SQL work, then SQLException can be thrown, and if you have code mistakes then NullPointerException etc.
Apache Camel may wrap exceptions in org.apache.camel.CamelExchangeException with the current Exchange if it happens during routing and it was detected and rethrown by Camel.
I know that a question like this probably depends on what the programmer intends his program to do however at school we were taught to never throw or catch Exception (the class) and rather make sure it throws one of the subclasses more specific to the kind of Runtime error we expect can happen (eg IllegalArgumentException). However, I'm working now and in the 'real world' I see a lot of scenarios in code I work on where the previous programmers threw Exception for everything in a method or catch Exception like that rather than one of its more specific subclasses.
So I'm wondering, Is it ok to throw and catch everything like this, is it bad programming to do so?
My idea is, the way of handle the exceptions should also depend on the type of the application you are creating. For example if you are developing some kind of a framework or a library you should not try to print error messages or log them, you have throw them because it will be responsibility of the other developers who are using your framework/library to handle the exceptions gracefully when they are using your code.
If you are developing some kind of a front end application then you should be more delicate with exception handling. I think it's better you use you own exception classes when possible, because that will help you to pin point the bugs or runtime issues in your application later. When you handle exceptions you should always go from more specific exceptions to general exceptions. And finally you should handle the exceptions of the "Exception" super class so it will make sure that your application doesn't crash, preferably you should have a try-catch block in the main entry point of your application. What ever happens in handling exceptions logging the errors is a good practice when it comes diagnosing the errors later.
It is not wrong to do that but it can make your debugging life very difficult. Many people will catch the exception class and log the Exception.Message. There is not enough detail and, especially if you're working on large systems where you can't always step through the live code etc, it will be a tedious task.
I tend to catch specific exceptions and handle them accordingly BUT I also catch the Exception class to make sure all exceptions are caught going forward (An object might be changed to include more exceptions in future framework versions).
It is bad practice, just as you have learnt.
One major exception to the rule is a top-level exception handler (to catch unhandled exceptions) - the purpose of this would be to log exception so they can be read by a developer later and used to fix the application (and would normally rethrow in order to crash the application - rather than leaving it in an inconsistent state).
The handlers I implemented override SimpleChannelHandler messageReceived, channelConnected and exceptionCaught methods.
Throwing a base Exception type means PMD complains "Signature Declare Throws Exception".
What is the best way to handle Netty exceptions so as not the throw base Exception types?
My guess is to remove the "throws Exception" from all my handlers. Then any exception that occurs will eventually get propagated up to the exceptionCaught() method in the last upstream/downstream Handler in the pipeline. Is this a correct assumption?
Although I happen to agree with PMD on this, the object model of Netty is different and uses a raw Exception. If you are programming against the Netty API, it would probably be better (for consistency, readability, etc.) to follow their model.
Don't let a static analysis tool be the deciding factor on your code. Sometimes there are exceptions (nice pun, not intended)
It dawned on me that I've never seen a single exception hierarchy for which creating subclasses but catching the parent class was actually useful (except, of course, for the base Exception class, that has to be derived).
Are exception hierarchies really useful, xor should all exceptions be derived from language's base exception class?
Exception hierarchies are useful for grouping related exceptions together, when you need different granularity of catching in different places.
Putting all application exceptions in one place is the commonest use case. This allows you to catch MyAppException any time that you want to trap all errors coming from your application, but still catch more specific exceptions when appropriate. (In .NET, the ApplicationException class was meant for this, but it's been deprecated for various reasons.)
But you can also group exceptions together at module boundaries, or in any other way that makes sense. Use FooModuleException for exceptions coming from the Foo module, but catch and handle FooModuleMustFrobnicate specially internal to Foo. Or any equivalent situation.
I've used all of these patterns at different times.
TL;DR
Exception hierarchies are useless for catching exceptions (except for base differentiation btw. non-recoverable system errors (Java Error) and "normal" runtime exceptions. The notion that "you need different granularity of catching in different places" is IMHO fundamentally flawed. (Except, to reiterate, to differentiate between exceptions and assertions and other system wide unrecoverable stuff.)
Small exception hierarchies make sense in todays languages as a means of constructing different errors with as rich information as possible.
I am slowly coming to consider the whole concept of arbitrarily typed exceptions, as I see them implemented and supposed-to-be-used in C++, C# and Java as totally useless.
The problem is not so much the exception hierarchy per se, but that when I write code, and exception are exceptional, I don't care what type of exception was thrown for the purpose of catching it.
In all my coding in C++, Java and C#, I found -- for the exceptional exceptions, that were not misused for control flow -- not one case where I wanted to filter (i.e. catch or not catch) the exceptions by their "hierarchical" type. That is, there are rare cases where a function throws 3 different exceptions, and I want to specifically handle one of them, and handle the two others as general "fail" (like described below) but I never ever encountered this in a case where the exception hierarchy was useful in that I could meaningfully group the two cases by base classes.
If any operation (where I care) in my program fails with any exception, then this operations is considered failed, and:
I get what info I can from the caught object
continue with contextualized error handling (re-throw, display error, log, re-try, recover, etc.)
I think Java is the only of the three languages that at least has the right approach with their hierarchy, namely:
Throwable not used in user code
Error the stuff you never want to catch - just core dump
Exception - for all the stuff you basically always want to catch (except for when an Interface is botched and uses an Exception when it really shouldn't)
//
The hierarchy of C++'s <stdexcept> has the right basic approach in differentiating between logic_error - basically assertions - and runtime_error - stuff that just unexpectedly failed. (The subclasses of theses are largely irrelevant when catching.)
Except of course that too much stuff derives directly from std::exception so you can't make use of the differentiation provided by runtime and logic error. (And of course any code is free to throw whatever they want, so chances are good that there's a bunch of logic_error derived classes that really should be runtime_errors and vice-versa.
To quote another answer:
Exception hierarchies are useful for grouping related exceptions
together, when you need different granularity of catching in different
places.
but in my experience I never want "catching in different places", because it just doesn't make sense.
I either want catching, in which case I catch everything (modulo stuff like the Error class exceptions from Java) or I don't want to catch, in which case the hierarchy is not needed, because there is no catch.
Take opening and reading from a file:
If there is (would be) any exception type I specifically care about, because I can do something about it ("recover"), then this should not be reported as an exception at all, because it is normal control flow. (If the error is such-and-such, I can do such-and-such basically locally.)
If on the other hand, I can't do anything about an error but record the file operation as failed, then having any catch granularity is utterly useless.
I've never created a single exception hierarchy for whole application, because an exception in general can bring different semantic and, therefore, needs to handled differently.
Some exceptions inform about system faults, another exceptions inform about bugs, and some other - about some exceptional condition, that could be gracefully recovered on higher level.
For this "business-logic" exceptions exception hierarchy can help you not to violate open-closed principle during overriding some methods in descendants.
Consider following example:
public abstract class Base
{
/// Perform some business-logic operation
/// and throw BaseFooException in certain circumstances
public abstract void Foo();
}
public class Derived1 : Base
{
/// Perform some business-logic operation
/// and throw DerivedFooException in certain circumstances.
/// But caller could catch only BaseFooException
public abstract void Foo() {}
}
class BaseFooException : Exception {}
class DerivedFooException : BaseFooException {}
Exception hierarchy may be helpful in custom framework or in specific libraries, but in general case (in business applications) I don't think that creating one deep and wide exception hierarchy is a good idea.
I've seen the following code many times:
try
{
... // some code
}
catch (Exception ex)
{
... // Do something
throw new CustomException(ex);
// or
// throw;
// or
// throw ex;
}
Can you please explain the purpose of re-throwing an exception? Is it following a pattern/best practice in exception handling? (I've read somewhere that it's called "Caller Inform" pattern?)
Rethrowing the same exception is useful if you want to, say, log the exception, but not handle it.
Throwing a new exception that wraps the caught exception is good for abstraction. e.g., your library uses a third-party library that throws an exception that the clients of your library shouldn't know about. In that case, you wrap it into an exception type more native to your library, and throw that instead.
Actually there is a difference between
throw new CustomException(ex);
and
throw;
The second will preserve the stack information.
But sometimes you want to make the Exception more "friendly" to your application domain, instead of letting the DatabaseException reach your GUI, you'll raise your custom exception which contains the original exception.
For instance:
try
{
}
catch (SqlException ex)
{
switch (ex.Number) {
case 17:
case 4060:
case 18456:
throw new InvalidDatabaseConnectionException("The database does not exists or cannot be reached using the supplied connection settings.", ex);
case 547:
throw new CouldNotDeleteException("There is a another object still using this object, therefore it cannot be deleted.", ex);
default:
throw new UnexpectedDatabaseErrorException("There was an unexpected error from the database.", ex);
}
}
Sometimes you want to hide the implementation details of a method or improve
the level of abstraction of a problem so that it’s more meaningful to the caller
of a method. To do this, you can intercept the original exception and substitute
a custom exception that’s better suited for explaining the problem.
Take for example a method that loads the requested user’s details from a text file. The method assumes that a text file exists named with the user’s ID and a suffix of “.data”. When that file doesn’t actually exist, it doesn’t make much sense to throw a FileNotFoundException because the fact that each user’s details are stored in a text file is an implementation detail internal to the method. So this method could instead wrap the original exception in a custom exception with an explanatory message.
Unlike the code you're shown, best practice is that the original exception should be kept by loading it as the InnerException property of your new exception. This means that a developer can still analyze the underlying problem if necessary.
When you're creating a custom exception, here's a useful checklist:
• Find a good name that conveys why the exception was thrown and make sure that the name ends with the word “Exception”.
• Ensure that you implement the three standard exception constructors.
• Ensure that you mark your exception with the Serializable attribute.
• Ensure that you implement the deserialization constructor.
• Add any custom exception properties that might help developers to understand and handle your exception better.
• If you add any custom properties, make sure that you implement and override GetObjectData to serialize your custom properties.
• If you add any custom properties, override the Message property so that you can add your properties to the standard exception message.
• Remember to attach the original exception using the InnerException property of your custom exception.
You typically catch and re-throw for one of two reasons, depending on where the code sits architecturally within an application.
At the core of an application you typically catch and re-throw to translate an exception into something more meaningful. For example if you're writing a data access layer and using custom error codes with SQL Server, you might translate SqlException into things like ObjectNotFoundException. This is useful because (a) it makes it easier for callers to handle specific types of exception, and (b) because it prevents implementation details of that layer such as the fact you're using SQL Server for persistence leaking into other layers, which allows you to change things in the future more easily.
At boundaries of applications it's common to catch and re-throw without translating an exception so that you can log details of it, aiding in debugging and diagnosing live issues. Ideally you want to publish error somewhere that the operations team can easily monitor (e.g. the event log) as well as somewhere that gives context around where the exception happened in the control flow for developers (typically tracing).
I can think of the following reasons:
Keeping the set of thrown exception types fixed, as part of the API, so that the callers only have to worry about the fixed set of exceptions. In Java, you are practically forced to do that, because of the checked exceptions mechanism.
Adding some context information to the exception. For example, instead of letting the bare "record not found" pass through from the DB, you might want to catch it and add "... while processing order no XXX, looking for product YYY".
Doing some cleanup - closing files, rolling back transactions, freeing some handles.
Generally the "Do Something" either involves better explaining the exception (For instance, wrapping it in another exception), or tracing information through a certain source.
Another possibility is if the exception type is not enough information to know if an exception needs to be caught, in which case catching it an examining it will provide more information.
This is not to say that method is used for purely good reasons, many times it is used when a developer thinks tracing information may be needed at some future point, in which case you get try {} catch {throw;} style, which is not helpful at all.
I think it depends on what you are trying to do with the exception.
One good reason would be to log the error first in the catch, and then throw it up to the UI to generate a friendly error message with the option to see a more "advanced/detailed" view of the error, which contains the original error.
Another approach is a "retry" approach, e.g., an error count is kept, and after a certain amount of retries that's the only time the error is sent up the stack (this is sometimes done for database access for database calls that timeout, or in accessing web services over slow networks).
There will be a bunch of other reasons to do it though.
FYI, this is a related question about each type of re-throw:
Performance Considerations for throwing Exceptions
My question focuses on "Why" we re-throw exceptions and its usage in application exception handling strategy.
Until I started using the EntLib ExceptionBlock, I was using them to log errors before throwing them. Kind of nasty when you think I could have handled them at that point, but at the time it was better to have them fail nastily in UAT (after logging them) rather than cover a flow-on bug.
The application will most probably be catching those re-thrown exceptions higher up the call stack and so re-throwing them allows that higher up handler to intercept and process them as appropriate. It is quite common for application to have a top-level exception handler that logs or reports the expections.
Another alternative is that the coder was lazy and instead of catching just the set of exceptions they want to handle they have caught everything and then re-thrown only the ones they cannot actually handle.
As Rafal mentioned, sometimes this is done to convert a checked exception to an unchecked exception, or to a checked exception that's more suitable for an API. There is an example here:
http://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html
If you look at exceptions as on an alternative way to get a method result, then re-throwing an exception is like wrapping your result into some other object.
And this is a common operation in a non-exceptional world. Usually this happens on a border of two application layers - when a function from layer B calls a function from layer C, it transforms C's result into B's internal form.
A -- calls --> B -- calls --> C
If it doesn't, then at the layer A which calls the layer B there will be a full set of JDK exceptions to handle. :-)
As also the accepted answer points out, layer A might not even be aware of C's exception.
Example
Layer A, servlet: retrieves an image and it's meta information
Layer B, JPEG library: collects available DCIM tags to parse a JPEG file
Layer C, a simple DB: a class reading string records from a random access file. Some bytes are broken, so it throws an exception saying "can't read UTF-8 string for record 'bibliographicCitation'".
So A won't understand the meaning of 'bibliographicCitation'. So B should translate this exception for A into TagsReadingException which wraps the original.
THE MAIN REASON of re-throwing exceptions is to leave Call Stack untouched, so you can get more complete picture of what happens and calls sequence.