Why are exceptions considered better than explicit error testing? [duplicate]

Possible Duplicate:
Defensive Programming vs Exception Handling?
if/else statements or exceptions

I often come across heated blog posts where the author uses the argument: “exceptions vs explicit error checking” to advocate his/her preferred language over some other language. The general consensus seems to be that languages that make use of exceptions are inherently better / cleaner than languages which rely heavily on error checking through explicit function calls.

Is the use of exceptions considered better programming practice than explicit error checking, and if so, why?

5

In my mind, the biggest argument is the difference in what happens when the programmer makes an error. Forgetting to handle an error is a very common and easy mistake to make.

If you return error codes, it is possible to silently ignore an error. For example, if malloc fails, it returns NULL and sets the global errno. So correct code should do

void* myptr = malloc(1024);
if (myptr == NULL) {
    perror("malloc");
    exit(1);
}
doSomethingWith(myptr);

But it is very easy and expedient to instead only write:

void* myptr = malloc(1024);
doSomethingWith(myptr);

which will unexpectedly pass NULL into your other procedure and likely discard the errno which was carefully set. There is nothing visibly wrong with the code to indicate that this is possible.

In a language that uses exceptions, instead you would write

MyCoolObject obj = new MyCoolObject();
doSomethingWith(obj);

In this (Java) example, the new operator either returns a valid initialized object or throws OutOfMemoryError. If a programmer must handle this, they can catch it. In the usual (and conveniently, also the lazy) case where it is a fatal error, the exception propagation terminates the program in a relatively clean and explicit manner.

That is one reason why exceptions, when properly used, can make writing clear and safe code much easier. This pattern applies to many, many things which can go wrong, not just allocating memory.

10

While Steven’s answer provides a good explanation, there is another point which I find is rather important. Sometimes when you check an error code, you cannot handle the failure case immediately. You have to propagate the error explicitly through the call stack. When you refactor a big function, you may have to add all the error-checking boilerplate code to your sub function.

With exceptions, you only have to take care of your main flow. If a piece of code throws some InvalidOperationError, you can still move that code to a sub function and the error management logic will be maintained.

So exceptions allows you to refactor faster and to avoid boiler plate.

6

A point of view from a different angle: Error handling is all about security. An unchecked error breaks all assumptions and preconditions the following code was based on. This may open a lot of external attack vectors: From a simple DoS over unauthorized data access to data corruption and complete system infiltration.

Sure, it depends on the specific application, but when assumptions and preconditions are broken, then all bets are off. Within a complex software, you simply can’t say anymore with certainty what is possible from then on, and what can and can’t be used from extern.

Given that, there is a fundamental observation: When security is treated as an optional add-on that can be attached later, then it fails most often. It works best when it was already considered in the very first basic design stages and built-in right from the start.

This is what you basically get with exceptions: An already built-in error handling infrastructure that is active even if you don’t care. With explicit testing, you have to build it yourself. You have to build it as a very first step. Just beginning to write functions that return error codes, without thinking about the big picture until you’re in the final stages of your application development, is effectively an add-on error handling, doomed to fail.

Not that a built-in system helps in any way. Most programmers don’t know how to do error handling. It’s just too complex most of the time.

  • There are so many errors that can happen, and each error requires its own handling and its own actions and reactions.

  • Even the same error can require different actions, based on context. What about a File Not Found or an Out Of Memory?

    • FNF – A third party library needed for your app to run? Terminate.
    • FNF – The start-up config file of your application? Start with default settings.
    • FNF – A data file on a network share the user wants your app to open? Disappearing files can happen anytime, even in the microseconds between Exists() and Open(). It’s not even an “Exception” in the literal meaning of the word.
    • OOM – For a 2GB allocation? No surprise.
    • OOM – For a 100 byte allocation? You’re in serious trouble.
  • Error handling leaks through all your carefully separated abstraction layers. An error in the lowest level may require to notify the user with a GUI message. It may require a decision from the user for what to do now. It may need logging. It may need recovery operations in another part, e.g. open database or network connections. Etc.

  • What about state? When you call a method on an object that invokes state changes and it throws an error:

    • Is the object in an inconsistent state and needs a rebuild?
    • Is the object state consistent but (partially) changed and needs an additional rollback or a rebuild?
    • Is a rollback done within the object and it remains unchanged to the caller?
    • Where is it even sensible to do what?

Just show me one learner’s book where error handling is rigorously designed from the start and consequently used through all the examples, without being left out for brevity and readability and as excercise for the reader. If this is applicable from an educational POV is another question, but it’s no surprise that error handling is often enough a second or third thought when it should be the very first.

12

I’d like to think of exceptions as…

They allow you to write code the way it naturally tends to be written

When writing code, there’s a number of things that the human brain needs to juggle:

  • What is the logic I am trying to express here?
  • How do I actually accomplish this in language XXXX?
  • How does this code fit into the rest of the application?
  • Why do I keep getting these build errors?
  • Am I forgetting about boundary conditions?
  • Is this code readable and maintainable enough?
  • What happens if something in this code fails?
  • Am I producing code in consistent style and use the right coding conventions?

Each one of these bullets requires a certain amount of concentration and concentration is a limited resource. This is why people who are new to a project will often forget things towards the bottom of the list. They are not bad people, but because so many things may be new to them (language, project, weird errors, etc…), they simply do not have the capacity to deal with other bullets.

I’ve done my share of code reviews and this trend is very apparent. A person with less experience will forget more things. These things include style and often enough error handling. When people are having a hard time getting the code to work, error handling tends to be in the back of their minds. Sometimes they’ll go back and add some if-statements here and there, but rest assured, they will forget a whole bunch of things.

Exception handling allows you to write code where the meat of your logic is written as though there are no errors. You make a function call and the next line can simply assume the previous line succeeded. This has an added bonus of producing code that is much easier to read. Have you ever seen an API reference with code examples that had a comment, “// Error handling omitted for clarity”? If they remove error handling in documentation to make the example easier to read, wouldn’t it be great if you could do the same thing in production code and make that easier to read as well? That’s exactly what exceptions let you do.

Now at least one person reading this post will say, “pffttt some noob doesn’t know how to code. I never forget error handling.” a) Good for you, but more importantly b) as I said above, coding requires your brain to concentrate and there’s only so much brain to go around; that applies to EVERYONE. If your code is easy to read, that’s less concentration. If you can put try/catch around a large chunk and then simply code application logic, that’s less concentration. Now you can use that extra capacity for more important things, like getting the actual job done that much faster.

Advantages of exception throwing over error code returning:

  • The return value of a function can be used for what it was designed to do: return the result of the function call, not a code that represents success or one of many failures within the function. This creates cleaner, more elegant code; fewer output/reference parameters, assignments are made to things you actually care about and not to throwaway status codes, etc.
  • Exceptions are object-oriented, so exception types have reusable conceptual meaning. What does a return code of -2 mean? You have to look it up in the documentation (which had better be good or you’re forced to trace code, and if you don’t have source code you’re really screwed). What does a NullPointerException mean? That you tried to call a method on a variable that doesn’t reference an instance. In addition, exceptions encapsulate data, so they can tell you exactly how and where your program screwed up in easily human-readable means. A return code can only tell you the method screwed up.
  • By default, return codes are ignored; exceptions aren’t. If you don’t store and check the return code, your program merrily continues along, corrupting data, screwing up pointers and generally crumpling itself into garbage. If you don’t catch an exception, it’s thrown out to the OS which terminates your program. “Fail fast”.
  • Exceptions are more easily standardized. Because exceptions create more self-documenting code, and because most of us don’t write all our programs 100% from scratch, exception types covering a wide variety of general cases are already available. The cheapest solution is the one you already have, so these built-in exception types get used in situations similar to the ones they were originally created for. Now, an InvalidOperationException means you tried to do something inconsistent with the current state of an object (exactly what that was will be detailed in the error message), regardless of which function from which third-party library you were trying to call.

    Contrast that with return codes; for one method, -1 might be a “null pointer error”, while -2 might be an “invalid operation error”. In the next method, the “invalid operation” condition was checked first and so that error got return code -1, while “null pointer” got -2. A number’s a number, and you are free to create any standard for assigning numbers to errors, and so is everyone else, leading to a LOT of competing standards.

  • Exceptions allow you to be more optimistic. Instead of pessimistically checking everything that could go wrong with a statement before actually executing the statement, you can simply try executing the statement, and catch any exceptions that were generated by it. If you can resolve the cause of the error and try again, great, if not, fine; you probably couldn’t have done anything about it had you known beforehand.

    Exception-based error-handling thus creates more efficient code by assuming it will work until it doesn’t. Guard statements that return early cost processor time; they should thus be used primarily when the benefits of checking up front outweigh the costs; if you can determine in a few clocks that the input will never produce a valid output, but it’ll take several seconds for the main body of the function to come to the same conclusion, then by all means put in a guard clause. However, if there are a dozen things that could go wrong, none of which are particularly likely and most of which require expensive execution, the “happy path” of normal program execution will be several times faster if you simply try/catch.

2

The fundamental difference for me is reading vs. writing:

Error code handling tends to clutter the intent: exception-based code is usually easier to read since the source focuses on the things that should happen, rather than what might.

OTOH, A lot of exception-based code is harder to write, because for a correctness analysis you have to argue about “unrelated” details, such as construction / destruction order, partially constructed objects, garbage collection etc.

How hard? This hard.

Generating meaningful exceptions can clutter the source as well, I have code bases where virtually every lines of code is followed by two or three lines building a literate exception.

For transferring meaningful exceptions to the top-level, they often need to be repackaged. When I click “rebicker cells”, an error message like “Sharing violation on %tmp%foofile536821” isn’t much more helpful than “Error 77”.


I really don’t have a preference, both options are equally ugly. What’s worse: which one is better seems to depend a lot on the project, in hard-to-predict ways. In my experience, low-level hardware interaction is smoother with error codes (might be the clients…), low level data access is better with exceptions.

8

Let’s put the implementation problems of many languages aside. The benefit exceptions have is that they can be centralized to handle all kinds(in theory) of exceptional states of the program. The problem they tackle is that exceptional things happen and can hardly ever be predicted. What is great(in theory) with exceptions is that you are safe as long as you:

  • Write exception safe code to highest degree possible
  • Catch the exceptional states via exceptions
  • Handle the exceptions accordingly

1

Exception-based code moves the error handling out of the main program flow. Instead the error handling is moved to either object destructor or to the catch construct.

The biggest advantage and also the biggest drawback with exception is that it does not force you to think about error handling. With exception, you often would just write straightforward code and let the the destructor does its job, and forgot about that one little scenario that the destructor does not handle and need to be done manually (which is clearly documented and therefore it’s totally your own fault for forgetting). The same scenario could happen with error code, but when writing code with error code, you are forced to check the manual/documentation/source all the time and it is less likely you’ll forget about that one little condition.

Yes, this mean exceptions might sometimes make it harder to write correct code.

Writing a bad code with error code is easy, writing a good code with error code is hard. Writing a decent code in exception is easy (because any errors terminates the program or is caught by a very high level handlers that could warn of the impending doom, instead of being passed around silently), writing good code with exception is really hard (because you’re handling the errors an arms away from the place where the error happens).

  • Easy to forget exit codes
  • Duplicate code. Checking the error code and returning the error code when there is an error would cause lots of duplicate code to handle and lots to change if the return type changes. Also what to do when different types can cause an error?
  • Exceptions are ran outside of the code path which means there is no work checking the return value. But there is work in the binary somewhere when the exception code is ran.
  • Easy to see what functions handles what type of errors. You dont have to look through a lot of code, just scroll through catch.
  • More details (in certain languages). It has built in information such as what line, function, etc. Putting that into a error class would be tedious. Likely you would only write function name and hopefully the type or cause of the error.
  • Debuggers understand exceptions are errors and may pause when it hits one while you are debugging. Tools help 🙂

If both are implemented perfectly the differences are not that much, however, usually nothing is perfect. If the handling of some errors is missing, in case of exceptions the program halts with a visible error, while the program with error testing just keeps running with undefined behavior.

If you develop a program and have an error you did not notice, what would you rather have?

  1. The program crashes so you start looking for and find the bug (or the program crashes at the beta testers, or maybe at the user so they can send in a bug report) (exception handling)
  2. The program keeps running, meanwhile silently corrupting some variables without causing any visible effects on your computer. However, it will delete all the users data when they run it, without them noticing when it happens. (error testing)

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật