Theory on error handling?

2019-03-07 13:14发布

Most advice concerning error handling boils down to a handful of tips and tricks (see this post for example). These hints are helpful but I think they don't answer all questions. I feel that I should design my application according to a certain philosophy, a school of thought that provides a strong foundation to build upon. Is there such a theory on the topic of error handling?

Here's a few practical questions:

  • How to decide if an error should be handled locally or propagated to higher level code?
  • How to decide between logging an error, or showing it as an error message to the user?
  • Is logging something that should only be done in application code? Or is it ok to do some logging from library code.
  • In case of exceptions, where should you generally catch them? In low-level or higher level code?
  • Should you strive for a unified error handling strategy through all layers of code, or try to develop a system that can adapt itself to a variety of error handling strategies (in order to be able to deal with errors from 3rd party libraries).
  • Does it make sense to create a list of error codes? Or is that old fashioned these days?

In many cases common sense is sufficient for developing a good-enough strategy to deal with error conditions. However, I would like to know if there is a more formal/"scholarly" approach?

PS: this is a general question, but C++ specific answers are welcome too (C++ is my main programming language for work).

14条回答
男人必须洒脱
2楼-- · 2019-03-07 13:41

Error handling is not accompanied by formal theory. It is too 'implementation specific' of a topic to be considered a science field (to be fair there is a great debate whether programming is a science on its own right).

Nontheless it a good part of a developer's work (and thus his/hers life), so practical approaches and technical guidliness have been developed on the topic.

A good view on the topic is presented by A. Alexandrescu, in his talk systematic error handling in C++

I have a repository in GitHub where the techniques presented are implemented.

Basically, what A.A does, is implement a class

template<class T>
class Expected { /* Implementation in the GitHub link */ };

that is meant to be used as a return value. This class could hold either a return value of type T or an exception (pointer). The exception could be either thrown explictly or upon request, yet the rich error information is always available. An example usage would be like this

int foo(); 
// .... 
Expected<int> ret = foo();
if (ret.valid()) {
    // do the work
}
else {
    // either use the info of the exception 
    // or throw the exception (eg in an exception "friendly" codebase)
}

While building this framework for error handling, A.A walks us through techniques and designs that produce successfull or poor error handling and what works or what not. He also gives his definitions of 'error' and 'error handling'

查看更多
ら.Afraid
3楼-- · 2019-03-07 13:43

How to decide if an error should be handled locally or propagated to higher level code?

If the exception breaks the operation of a method it is a good approach to throw it to higher level. If you are familiar with MVC, Exceptions must be evaluated in Controller.

How to decide between logging an error, or showing it as an error message to the user? Logging errors and all information available about the error is a good approach. If the error breaks the operation or user needs to know that an error is occur you should display it to user. Note that in a windows service logs are very very important.

Is logging something that should only be done in application code? Or is it ok to do some logging from library code.

I don't see any reason to log errors in a dll. It should only throw errors. There may be a specific reason to do of course. In our company a dll logs information about the process (not only errors)

In case of exceptions, where should you generally catch them? In low-level or higher level code? Similar question: at what point should you stop propagating an error and deal with it?

In a controller.

Edit: I need to explain this a bit if you are not familiar with MVC. Model View Controller is a design pattern. In Model you develop application logic. In View you display content to user. In Controller you get user events and call Model for relevant function then invoke View to display result to the user.

Suppose that you have a form which has two textboxes and a label and a button named Add. As you might guess this is your view. Button_Click event is defined in Controller. And an add method is defined in Model. When user clicks, Button_Click event is triggered and Controller calls add method. Here textbox values can be empty or they can be letters instead of numbers. An exception occur in add function and this exception is thrown. Controller handles it. And displays error message in the label.

Should you strive for a unified error handling strategy through all layers of code, or try to develop a system that can adapt itself to a variety of error handling strategies (in order to be able to deal with errors from 3rd party libraries).

I prefer second one. It would be easier. And I don't think you can do a general stuff for error handling. Especially for different libraries.

Does it make sense to create a list of error codes? Or is that old fashioned these days?

That depends on how will you use it. In a single application (a web site, a desktop application), i don't think it is needed. But if you develop a web service, how will you inform users for errors? Providing an error code is always important here.

If (error.Message == "User Login Failed")
{
   //do something.
}

If (error.Code == "102")
{
   //do something.
}

Which one do you prefer?

And there is another way for error codes these days:

If (error.Code == "LOGIN_ERROR_102") // wrong password
{
   //do something.
}

The others may be: LOGIN_ERROR_103 (eg: this is user expired) etc...

This one is also human readable.

查看更多
登录 后发表回答