Proper and good error handling and generation is a rather important part in software development. But how to do it correctly and beautifully is not enough advice, and they are very superficial. Please explain the principles of good error handling (preferably in Java ) along with examples.

UPD1 :

  1. When to make a RuntimeException , and when just Exception ?
  2. Is the only way to generate an error with a throw statement?
  3. In what cases is it better to create, say, MyException extends Exception , and then MyOtherException extends MyException ? In other words, how to see the need for a hierarchy of errors?
  4. When to do something like this:

     public void f() throws MyException { //некоторый код ... if (....){ throw MyException(...); } } 
  5. What are some other ways to generate errors?

  6. When is it more correct to transfer the error to the function level ( ... f() throws ... )?
  • Yes, but the question was something else. I did not ask how the generation and error trapping takes place. The question is how well to design a convenient and high-quality system for creating your own exceptions, catching them, etc. - Anton Mukhin
  • Do you have time to do this nonsense)? Everyone writes from textbooks, tests and sells the product, gains experience from their own mistakes, and then it becomes clear how to work with them. The Germans, they say, write a function that checks whether the function that handled the error worked correctly;) - kavamarov
  • 7
    The one who does not know how to find time for this - he does not know how to make quality products. Product diagnostic tools in combat conditions are one of the indicators. A vivid example is Windows: if something breaks, it breaks almost without words .. and there is no way to understand what happened. Just guessing. That is why so often you have to reinstall it. - cy6erGn0m
  • 2
    Read chapter 9 of the classic book Effective Java Second Edition by Joshua Bloch . Most of the issues related to exceptions are addressed there. - test81278
  • one
    As a rule, the information is useless there, or the system is in such a state that it is not possible to get to this journal. - cy6erGn0m

1 answer 1

First, as already mentioned, use exceptions. Create your own hierarchy of exceptions and think about which of them make runtime and which not. Never use constructions like new Exception(...) or new RuntimeException . Instead, try to create and throw only adequate situations of exclusion. Instance creation Exception or RuntimeException - hack and unsubscribe instead of error handling.

Do not forget to check all the parameters in the constructors and, if possible, in the methods and promptly throw an IllegalArgumentException . Use standard exceptions as appropriate. Use them for their intended purpose and never throw anything.

Use try / catch / finally . Do not forget to destroy resources.

Use loggers instead of e.printStackTrace . Never make catch empty unless you are sure that you must ignore the exception.

When logging, use the full log method with the logging level, message, and exception. Try to describe in the message to the log what exactly fell and add some information about the conditions in the try block. This will help identify problems in combat conditions. Try to assign adequate levels of logging.

Customize the logger. In some cases, you should separate the logs for errors and variations. Otherwise, error messages can be lost and lost due to less important messages.

Hook something like an audit if the application is server-side. Perhaps it is worth it in especially fatal cases to send a letter to admins.

If this is a client application on a swing, then you can display an error message from the window or as a small icon in the status bar.

UPD1

When to make a RuntimeException , and when just Exception ?

This is a rather complicated question and difficult to give general recommendations. But in general, one should be guided by the fatality of the error and its probability of occurrence. You should also consider the possible distance from the place of error generation to the place of actual processing. For example, IOException cannot simply not be processed in any way and this is true. If it is not processed, then some resources may get stuck. And usually the processing of such an error is relatively close to its place of origin. At the same time, IllegalArgumentException can not be caught ... because usually these are errors related to incorrect use of the API, incorrect configuration or insufficient validation of data from the user. And an attempt to catch such exceptions everywhere would lead to a crash: the code would simply be unreadable. In other words, common sense is required.

Is the only way to generate an error with a throw statement?

No, it is not necessary to throw an exception. For example, in GWT (and not only) there is an AsyncCallback interface that has an onError method that accepts an exception as a parameter. The corresponding code does not throw exception through throw , but simply calls the callback method and passes the exception there. And the callback itself will decide what to do with this exception.

In what cases is it better to create, say, MyException extends Exception , and then MyOtherException extends MyException ? In other words, how to see the need for a hierarchy of errors?

Obviously in cases where between the exceptions may be some kind of "related" connection. When some exception groups have something in common.

When to do something like this:

 public void f() throws MyException { //некоторый код ... if (....){ throw MyException(...); } } 

Always, if if allows you to determine that something went wrong.

What are some other ways to generate errors?

Actually, assert , throw and just calling the handler with an exception parameter.

When is it more correct to transfer the error to the function level ( ... f() throws ... )?

Again, the best example is an IOException . This should always be done when there is an error, but you know for sure that the client (the caller of your method) may want to know about the error explicitly, and not by indirect signs. So, for example, if someone reads from a socket, then he wants to know that reading is impossible and simply to prepend the operation instead of checking every time whether the socket is working or making infinite ifs checking the error code after each read method.

UPD

Yes, perhaps, in my opinion, a good example of the wrong choice between Exception and RuntimeException is InterruptedException . It would be much better if it was Runtime . As a result, either everywhere you have to catch and ignore him, or throw around everywhere ... thinking up a case that will never happen. And these blockages badly spoil the code.

  • I apologize for illiteracy, and what is possible instead of new Exception(...) или new RuntimeException ??? - Anton Mukhin
  • throw new SomeConcreteAndAdequateException - cy6erGn0m
  • Thanks for the intelligible and instructive answers! Probably from general advice, there is nothing more to add. The rest of the experience? - Anton Mukhin
  • I'm afraid yes :) - cy6erGn0m
  • вызывает callback-метод и передаёт туда исключение. А уж callback сам решит, что с этим исключением делать. YES THIS IS A GENIUS METHOD !!!!! - Anton Mukhin