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.
Related
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
I am trying to intercept an Exception thrown by my algorithm in Java, and change the text to another language, and show it to the user. Is this possible in java?
Sorry by my English.
You can catch an exception, and then throw a new one of the same type (or a different type if you prefer). Then translate the message from the original exception and pass it into the new exception. Something like the following (not tested):
try {
// do something
}
catch (Exception e) {
throw new Exception(translate(e.getMessage()))
}
public String translate(String message) { /* translation code */ }
Update in response to comment:
If you can modify the application (and particularly if the application uses custom exceptions derived from a few base classes) then you might be able to modify these to retrieve translated messages (but if you could do that, you could build in the translated messages, or full internationalisation, from the start!).
Intercepting and replacing all Exceptions globally is probably not possible, although it looks like you can at least detect them globally using debug hooks - see this answer. It's conceivable that you could modify the Exception message on-the-fly using reflection, but this sounds pretty nasty.
One final possibility is to use Aspect-Oriented Programming (AOP) to compile-in extra behaviour around code that throws an exception (see this question, for example). You'd need to recompile the whole application using AOP tools though, and would probably still need to modify the application code a bit.
I think you want Thread.setDefaultUncaughtExceptionHandler()
This issue had more details if you need them...
swing uncaughtexceptionhandler
You would need to translate the message text of an exception only if your were reporting the message text of exceptions. But doing that is a mistake.
The message was created when the exception was thrown. It therefore at best can provide only very low level information, which can be inappropriate for reporting to a user.
Philosophically, using the message is against the whole point of exceptions, which is to separate the detection and initiation of error handling (the throw part) from completion of handling and reporting (the catch part). Using the message means the message must be good for reporting, which moves responsibility for reporting to the location that should be responsible for only detection and initiation. That is, I'd argue that the getMessage() part of the design of Throwable was a mistake.
Instead of doing that, follow the advice to choose what message to report to the user at the point where your catch the exception. You can internationalize that message use the usual Java text internationalization facilities.
I solved my question with this solution
public class ParamsException extends RuntimeException {
private static final long serialVersionUID = 7161500238672497882L;
public ParamsException() {
super();
}
public ParamsException(String message) {
super(new BaseResourcesBusiness().getException(message));
}
public ParamsException(Throwable cause) {
super(cause);
}
public ParamsException(String message, Throwable cause) {
super(new BaseResourcesBusiness().getException(message), cause);
}
}
the BaseResourceBusiness.getException(message) get the message from a XML or Database to a specific language. So all my exception is created in this mode
public static final class NotFoundInDatabaseException extends ParamsException {
private static final long serialVersionUID = -1595240938885629473L;
public NotFoundInDatabaseException () {
super("Not found in database");
}
}
in the code im using with this mode throw new NotFoundInDatabaseException ()
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.)
How can I detect when an Exception has been thrown anywhere in my application?
I'm try to auto-magically send myself an email whenever an exception is thrown anywhere in my Java Desktop Application. I figure this way I can be more proactive.
I know I could just explicitly log and notify myself whenever an exception occurs, but I'd have to do it everywhere and I might(more likely will) miss a couple.
Any suggestions?
You probobly don't want to mail on any exception. There are lots of code in the JDK that actaully depend on exceptions to work normally. What I presume you are more inerested in are uncaught exceptions. If you are catching the exceptions you should handle notifications there.
In a desktop app there are two places to worry about this, in the event-dispatch-thread (EDT) and outside of the EDT. Globaly you can register a class implementing java.util.Thread.UncaughtExceptionHandler and register it via java.util.Thread.setDefaultUncaughtExceptionHandler. This will get called if an exception winds down to the bottom of the stack and the thread hasn't had a handler set on the current thread instance on the thread or the ThreadGroup.
The EDT has a different hook for handling exceptions. A system property 'sun.awt.exception.handler' needs to be registerd with the Fully Qualified Class Name of a class with a zero argument constructor. This class needs an instance method handle(Throwable) that does your work. The return type doesn't matter, and since a new instance is created every time, don't count on keeping state.
So if you don't care what thread the exception occurred in a sample may look like this:
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable throwable) {
try {
// insert your e-mail code here
} catch (Throwable t) {
// don't let the exception get thrown out, will cause infinite looping!
}
}
public static void registerExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
}
}
Add this class into some random package, and then call the registerExceptionHandler method and you should be ready to go.
The new debugging hooks in Java 1.5 let you do this. It enables e.g. "break on any exception" in debuggers.
Here's the specific Javadoc you need.
Check out Thread.UncaughtExceptionHandler. You can set it per thread or a default one for the entire VM.
This would at least help you catch the ones you miss.
If you're using a web framework such as Spring then you can delegate in your web.xml to a page and then use the controller to send the email. For example:
In web.xml:
<error-page>
<error-code>500</error-code>
<location>/error/500.htm</location>
</error-page>
Then define /error/500.htm as a controller. You can access the exception from the parameter javax.servlet.error.exception:
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
If you're just running a regular Java program, then I would imagine you're stuck with public static void main(String[] args) { try { ... } catch (Exception e) {} }
If you are using java 1.3/1.4, Thread.UncaughtExceptionHandler is not available.
In this case you can use a solution based on AOP to trigger some code when an exception is thrown. Spring and/or aspectJ might be helpful.
In my current project I faced the similar requirement regarding the errors detection. For this purpose I have applied the following approach: I use log4j for logging across my app, and everywhere, where the exception is caught I do the standard thing: log.error("Error's description goes here", e);, where e is the Exception being thrown (see log4j documentation for details regarding the initialization of the "log").
In order to detect the error, I use my own Appender, which extends the log4j AppenderSkeleton class:
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class ErrorsDetectingAppender extends AppenderSkeleton {
private static boolean errorsOccured = false;
public static boolean errorsOccured() {
return errorsOccured;
}
public ErrorsDetectingAppender() {
super();
}
#Override
public void close() {
// TODO Auto-generated method stub
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
if (event.getLevel().toString().toLowerCase().equals("error")) {
System.out.println("-----------------Errors detected");
this.errorsOccured = true;
}
}
}
The log4j configuration file has to just contain a definition of the new appender and its attachement to the selected logger (root in my case):
log4j.rootLogger = OTHER_APPENDERS, ED
log4j.appender.ED=com.your.package.ErrorsDetectingAppender
You can either call the errorsOccured() method of the ErrorsDetectingAppender at some significant point in your programs's execution flow or react immidiately by adding functionality to the if block in the append() method. This approach is consistent with the semantics: things that you consider errors and log them as such, are detected. If you will later consider selected errors not so important, you just change the logging level to log.warn() and report will not be sent.
In this case I think your best bet might be to write a custom classloader to handle all classloading in your application, and whenever an exception class is requested you return a class that wraps the requested exception class. This wrapper calls through to the wrapped exception but also logs the exception event.
I assume you don't mean any Exception but rather any uncaught Exception.
If this is the case this article on the Sun Website has some ideas. You need to wrap your top level method in a try-catch block and also do some extra work to handle other Threads.
Sending an email may not be possible if you are getting a runtime exception like OutOfMemoryError or StackOverflow. Most likely you will have to spawn another process and catch any exceptions thrown by it (with the various techniques mentioned above).
There is simply no good reason to be informed of every thrown exception. I guess you are assuming that a thrown exception indicates a "problem" that your "need" to know about. But this is wrong. If an exception is thrown, caught and handled, all is well. The only thing you need to be worried about is an exception that is thrown but not handled (not caught). But you can do that in a try...catch clause yourself.
At the moment i working with library which can throw hell alot of different exceptions(8-10 per method call) and most of them must be handled, worse of all every method (at any time) can throw AuthenticationExpiredException, and i must re-attempt to authenticate. For example:
try {
xStream = xSet.createXStream(id, binding, mimeType); //Method call
} catch (AuthenticationExpiredException authenticationExpiredException) {
try {
this.authenticate(); // re-authenticate
xStream = xSet.createXStream(id, binding, mimeType); //Method call again
} catch (XAMException xamException) {
throw new ConnectorException(
"Error occurred during creating new Blob after attempting to re-authenticate",
xamException);
}
} catch (XSystemCorruptException xSystemCorruptException) {
this.entities.clear();
this.closeConnection();
throw new ConnectorException("XSystem was corrupt and connection was closed",
xSystemCorruptException);
} catch (XSetCorruptException xSetCorruptException) {
this.closeEntity(entity);
throw new ConnectorException("XSet for entity: " + entity.getXuid()
+ " was currupt and removed", xSetCorruptException);
} catch (XAMException xamException) {
throw new ConnectorException(
"Error occurred during creating new Blob.", xamException);
}
And this is one of the smallest examples of exception handling. The main question here, is there any way to reduce amount of code which handle exceptions, and make logic cleaner?
UPDATE
Thanks for your feedback. I decided to create separate wrapper for this library by wrapping every method and handling them respectively. To support different handling methods i created interface for wrapper and then implemented it with my custom wrapper like this:
public interface XAMLibraryWrapper{
// Methods
}
/**
* Will attempt to recover before throwing RuntimeException
*/
public class RecoveringXAMLibraryWrapper implements XAMLibraryWrapper{
// Implementation
}
If there is a consistent way to handle those method (i.e. you always wrap them in the same way and re-throw a RuntimeException, then a custom wrapper library might be the appropriate approach. This can still work when there are 2-3 different ways to handle them (by providing 2-3 wrapper methods (or even classes) for a single wrapped method/class).
Alternatively, if two or more exception types have the exact same handling code, then you can try to look for Java 7 to get multi-catch.
You can use Template method pattern. JdbcTemplate is a wonderful example how this design pattern can simplify exception-heavy code (SQLExceptions in this case).
If the API is indeed designed to throw that many exceptions, and each of them requires different handling, then there isn't much you can do.
One thing you can do is move repeated code in a separate method, or use Java 7 multi-catch.
If you have different things to do for each exception I'm afraid all those catch statements might be necessary. However, if you have lot's of catch statements with the same content or lot's of resources to close, you might have a look into the new Java 7 features like multiple exceptions in one catch and automatic resource handling. I'm not sure Java 7 is an option for you though.