Exception Handling Strategy - Reuse Exception Codes

I am working on an application in which the process is as follows

UI --> backend process --> result to UI. 

In my Java code, I handled my exceptions using try-catch. But in the code, I have so many repeated exceptions that can throw the same exceptions in different classes, which reduces the readability and reuse of the code.

So, I plan to make an exception handling strategy so that instead of throwing the same exception in different classes, I need to throw an exception and reuse the exception codes.

Can someone suggest me a better exception handling method for this?

+4
source share
5 answers

Always handle Unchecked Exceptions as close to their source as possible, but don’t create them; they are inherently unsafe idioms of last resort programming; when there is no way to restore the program.

When implementing the application, the code always protects the purchase using verified coding exceptions to manage exceptional workflows; for example, when your code does not execute its " Contract " interface.

The application should not crash with an uncontrolled exception, because it cannot get into the third-party credit rating system. Disable this option and continue creating client clients.

Generalize exception handling, but specialize in creating them. eg.

 CustomerNotFound extends CustomerException CreditCustomerNotFound extends CustomerException CashCustomerNotFound extends CutomerException { aCustomer = customerList.find( ... ) } catch CustomerNotFound() { logger.warn( ... ) throw CustomerException(CustomerNotFound) } InvoiceAddressException extends InvoiceException 

Perform specific processing as close to the source as possible, log details and clear as much as possible. Advocate only

Perform overall processing and reporting as close to the user interface as possible.

+3
source

Since you have a GUI that will be used by the client, the client will need to know if an exception has occurred, so the best place to handle exceptions will be your top layer (the one that binds to the GUI).

You can also catch exceptions when they are thrown, log them, and then throw them back.

This means that all other lower levels will simply throw an exception.

You can create some custom exceptions and use them instead of the usual ones (for example, catch SqlException and throw MyDBException with more detailed information, for example, exception code, query string, etc.)

EDIT

I would also like to consider the possibility of eliminating exceptions from 2 categories: logical and functional.

  • A logical problem with the application logic, for example, when a user tries to log in with an invalid username / pwd, these errors will usually be thrown by you specially and will create user errors.
  • Functional - all regular exceptions that arise due to problems in the application itself (for example, connecting to DB, etc.).

Then you can choose a strategy to handle each type. Logical exceptions return certain data to the user (invalid username / pwd), and Functinal exceptions return a more general message like: a problem has occurred, contact support.

+2
source

I would like to show a design-oriented approach,

  • firstly, Martin Spammer is right, because we need to catch only the checked exception .... but at a very granular level ... for example. Invalid InvalidCredentialException and AuthorizationException should not be selected as loginException, because suppose you select it as an exception of the same type, and then you will be asked to handle these types differently in the future, then

  • secondly, there are UI levels ----> front level ----> service level -----> DAO level

Logic should be

(i) the front-tier receives the request from the user interface and handles the checks / exceptions based on the interface (for example, MissingUserNameException at login). If everything is in order, then request forwarding to the service level

(ii) the service will check the logic of the business and if it is valid, then it will process the request. If this is not an exception with the correct message to the interface level

(iii), but each service level exception message may not be suitable for the user to display. therefore, the front-level responsibility should be to convert a business exception to a client read exception

This approach will have another added advantage. Suppose a requirement arises when you need to expose some business methods as a web service ... so that your services will be exposed anyway. Now, if you put all the exception handling (i.e., converting the exception into the correct message), the logic at the interface level and service level is not fully aware of them ... then it will be a mess when you need to reorganize your service level code again (and also front level). Even a few times later, a different situation may arise: your front-end technology becomes obsolete, and you will have to re-encode all the exception handling logic in the new technology.

So, the bottom line , the service level should know + handle all business validation exceptions using the correct message. After throwing the exception with the correct message, it will pass it to the client level from which the service is called. Now it is the responsibility of the client level to display the message and decorate it again with some other message, if necessary. This way you can keep all levels independent.

+1
source

Instead of writing more comments (superfluous superfluous), I will give some of my thoughts + one of the general solutions with which I came.

http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html

This puts this question in a simple context. When people are not accustomed to exceptions (e.g. script / functional programmers), they write about using only RuntimeExceptions ..., which makes you pollute the external interface with unmanaged errors that occur in the user interface. (I do not think this is very convenient if you consider the program code in the long run ... maintainability)

http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html

If the client can take some alternative action to recover from the exception, make it a checked exception. If the client cannot do anything useful, make the exception unchecked. By usefulness, I mean taking measures to recover from an exception, and not just to register an exception.

(There are messages about registering templates with Exceptions, but I'm not going to go there on this, since this is moving away)

Unchecked exceptions are hard to spot, and they easily access your "close to source". (If they are not checked, they will be invisible to the client code and slip through).

I was questioned by this problem with some legacy code throwing a lot of unchecked exceptions that now lead to a crash in the user interface. (due to unreliable services)

Everyone probably has their own opinion on what to do, but I'm trying to create a common template for detecting errors (excluded exceptions) close to the user interface and presenting them as tooltips (JSF by the way) instead of guiding the user to the page "error.xhtml" (entered in web.xml).

// For the above scenario, I came up with this solution.
It seems to work very well.

  • Create annotation of interceptor and interceptor binding.
  • Annotate classes or methods that you want their bubbling EJBExceptions to be sanitized.
    • Do not intercept everything, otherwise you get unnecessary processing / overhead. Just use it where you really need it, at the BackingBean / ManagedBean level.

Interceptor Binding Annotations

 @Inherited @InterceptorBinding @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface InterceptEJBExceptions {} 

Interceptor

 @Interceptor @InterceptEJBExceptions public class EjbExceptionInterceptor { @AroundInvoke public Object interceptBubblingExceptions(final InvocationContext context) throws Exception { try { return context.proceed(); } catch (MySpecificEJBException msejbe) { Object[] args = { msejbe.getErrorCode(), msejbe.getMethodSignature(), msejbe.getParameters()}; // This would create a FacesMessage in JSF addErrorMessageToFacesContext(null, summary_template, details_template, args); } catch (EJBException ejbe) { super.addErrorMessageToFacesContext(null, "Unspecified EJBException", ejbe.getMessage()); } // "Pure" RuntimeExceptions will fall through and will be shown on 'error-page' specified in web.xml return null; } } 

beans.xml

 <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>xxx.xxx.xxx.exception.interceptor.EjbExceptionInterceptor</class> </interceptors> </beans> 

Using java classes

 @RequestScoped // Class must be in EE context // @InterceptEJBExceptions // Have the annotation at class level to intercept all method calls in this class public class MyBB { @InterceptEJBExceptions // Only intercept when this method gets called public String myEjbExceptionThrowingActionListener(Object obj) { // Some code that may throw an EJBException } } 

MySpecificEJBException . There will be an exception class extending an EJBException . Build the class the way you like to transfer useful information for later logging and to display clean error messages on the screen instead of throwing an exception on the screen with or without the error page defined in web.xml (which you should also have as backup copy).
Remember to include the original exception in the class!

Create more custom Exceptions that extend the EJBException as needed, and throw them as you wish (they are not marked as RuntimeExceptions). Then simply add the catch block to the interceptor and make a message about registration and / or error displayed for this case.

Generally:

  • Use proven Exceptions where you can respond to errors.

    • In Java 7, you can use the following syntax to group exceptions that can be handled similarly.

      try {...} catch (SomeException | OtherException e) {...}

  • If you have many test Exceptions, you can / should possibly group them into categories (extend an even more general exception). You can then catch groupings based on this exception (in addition to / instead of catch-clauses grouping).

  • Turn these exceptions into EJB / RuntimeExceptions that pollute you with code (if you really have nothing to do). They should then be captured and handled by a common EjbExceptionInterceptor. The interceptor will catch an exception => show an error message / pop-up message, but the user will remain on one page without losing the data on which he / she worked.
  • Avoid throwing the usual RuntimeException. They signal an error in the code (my opinion), and the aforementioned interceptor will allow them to fail on the error page. It will also disconnect the user from the page on which he is currently located.
    • These errors should always be fixed with high priority (for example, NullPointerException will do this).
    • Also: do not throw exceptions about almost everything, it will be poor programming. If your code can do something with an error before hand (for example, use overloaded methods or default values ​​to prevent the use of null parameters), then do this, do not miss the problem to the client (call method). This is just lazy programming + using RuntimeExceptions to hide these errors is simply irresponsible! Trial Tests!


I could not find a real solution for error handling (like a template), but there is a lot of debate about what is right and what is wrong. We have 2 types of Throwables, so why don't they use them as constructively?
Instead of continuing this discussion, I hope it will be a real solution and a trick.

I would be grateful for all constructive comments and suggestions for improvement.

0
source

Edit: The original answer moved here to another question: fooobar.com/questions/1427026 / ...

To keep your answer in the field of questions, here are the interesting parts:

Avoid Exception Codes

The type of exception should be sufficient to make flow control decisions. Exception parsing or flow control will produce useless code. Add more exception types as many exception codes you have.

Paragraph 39: Use exceptions for exceptional conditions only (Jochua Bloch Effective Java Chapter) :

Paragraph 39: Use exceptions only for exceptional conditions. That is, do not use exceptions for the control flow, such as catch NoSuchElementException when calling Iterator.next () instead of first checking Iterator.hasNext ().

In functional languages, we use exceptions only for truly exceptional conditions. An exceptional condition is something like "it is impossible to connect to the database", and not something like "the user did not provide the required number of articles in the input text." This is not exceptional, this is a business error.

The Java language does not help much, but ideally you can return this business error as a function output (for example, an instance of EnumAddBasketError) instead of creating an AddProductToBasketWithoutQuantityException. In practice, people tend to raise an exception, disrupting the normal flow of control and slowing down the application (exceptions have a cost).

Avoid Marked Exceptions

Read my other answer here: fooobar.com/questions/1427026 / ... Checked exceptions relate to recoverable failures (Sun recommendations). Excluded exceptions are easier to handle for fatal crashes.


In the end, I mean that you probably do not need all of these exceptions, because most of them are probably not recoverable or cannot be exceptional.

-2
source

All Articles