Is it good practice to always catch an exception i

2019-07-17 01:13发布

As a project gets bigger and bigger, I get a bit confused as to what types of exceptions should be thrown and where they should be caught, e.g. how to organize internal exceptions vs exception messages that should be shown to the end user. To keep confusion down, is it best practice to always catch an exception in the higher-level object?

Take this example: if I have a database class that inserts a row into the database, and that class is called by another object that processes data, and in turn this data processing object is called by a controller, is it correct to catch errors from the database class in the processing class, which (possibly) rethrows the error to be caught in the controller class? Or can an error thrown in the database class be caught in the controller class?

Additionally, if one method in the processing class is called by another method in the same class, and the first throws an error, is it ok to catch the exception in the same class? Or should it be deferred to the higher-level class that's calling it?

Are there any other tips on how to structure and organize exceptions in large projects with many levels of classes?

2条回答
狗以群分
2楼-- · 2019-07-17 01:54

I like to think about exceptions as expected events that may interrupt your normal program flow but in an orderly and controlled way. The task of your exception handling is to deal with this situation and resolve it in such a way that your program state remains valid and the application can continue.

Therefore you should add the exception handling at the first place up the calling hierarchy where you are actually able to resolve the situation. This may include cleaning up previously opened resources which are now no longer needed, logging the event or providing feedback to the user.

In your example I would probably leave the handling logic to the controller. The database often does not have enough context of what has just happened and how to deal with specific conditions since those depend on the context in which the database has been called. Your controller on the other hand should have all context information and should be well aware of what the program just tried to do. It is also probably better suited to resolve the issue for example by displaying a general error message to the user and maybe send detailed error report to the administrator.

Sometimes you will also have the situation where you need to catch exception on an intermediate level, to do some cleanup (like closing streams or rolling back some actions) and then rethrow the exception because you know that you did only resolve part of the situation.

All in all may general recommendation is to think about what actions need to be done to resolve such an exceptional event and then implement the error handling where those actions can be done easily.

查看更多
时光不老,我们不散
3楼-- · 2019-07-17 01:54
  1. An exception should be thrown in an exceptional event, i.e. if something is seriously wrong and the code cannot continue as is. E.g. database is down, remote service is not responding, seriously malformed input received.
  2. If you catch an exception, you need to know what to do with it. When an exception has been raised, it means your application is in a serious error state. If you catch the exception, you should have a serious plan on how to proceed from this error state. If you don't have a plan, there's no point in catching it. If the database is down, you will probably want to stop the program. On the other hand, if a remote HTTP request yielded a 404 response and your HTTP handler is throwing that as an exception, you will probably be able to live with that error and continue (depending on what that request was supposed to be used for).
  3. Raw exception messages should never be shown to endusers. The exception needs to be logged, but the enduser should only see a generic nice "Oops, something went wrong, maybe you want to try X instead...?" message. This is not specific to exceptions, it's just good UX design.
查看更多
登录 后发表回答