views:

904

answers:

15

Yesterday I was having a heated debate with a coworker on what would be the preferred error reporting method. Mainly we were discussing the usage of exceptions or error codes for reporting errors between application layers or modules.

What rules do you use to decide if you throw exceptions or return error codes for error reporting?

+15  A: 

I normally prefer exceptions because they have more contextual information and can convey (when properly used) the error to the programmer in a more clear fashion.

On the other hand error codes are more lightweight than exceptions but are harder to maintain and error checking can inadvertedly be omitted. They are harder to maintain because you have to keep a catalog with all error codes and then switch on the result to see what error was thrown. Error ranges can be of help here because if the only thing we are interested in is if we are in the presence of an error or not is simpler to check (with an HRESULT error code greater or equal to 0 is success and less than zero is failure). They can inadvertedly be ommitted because there is no programmatic forcing that the developer will check for error codes. On the other hand you cannot ignore exceptions.

To resume I prefer exceptions over error codes in almost all situations.

smink
+10  A: 
JamShady
+1  A: 

In the past I joined the errorcode camp (did too much C programming). But now I have seen the light.

Yes exceptions are a bit of a burden on the system. But they simplify the code, reducing the number of errors (and WTF's).

So use exception but use them wise. And they will be your friend.

As a side note. I have learned to document which exception can be thrown by which method. Unfortunately this is not required by most languages. But it increases the chance of handling the right exceptions at the right level.

Gamecat
yap C does leave a few habits in us all ;)
smink
+1  A: 

Method signatures should communicate to you what the method does. Something like long errorCode = getErrorCode(); might be fine, but long errorCode = fetchRecord(); is confusing.

Paul Croarkin
+3  A: 

Error codes can be ignored (and often are!) by the callers of your functions. Exceptions at least force them to deal with the error in some way. Even if their version of dealing with it is to have an empty catch handler (sigh).

A: 

Error codes also don't work when your method returns anything other than a numeric value...

Omar Kooheji
Um, no. See win32 GetLastError() paradigm. I am not defending it, just poiting out that you are incorrect.
Tim
A: 

For most applications, exceptions are better. The exception is when the software has to communicate with other devices. The domain I work in is industrial controls. Here errors codes are preferred and expected. So my answer is that it does depend on the situation.

Jim C
+5  A: 

Exceptions over error codes, no doubt about it. You get much of the same benefits from exceptions as you do with error codes, but also much more, without the shortcomings of error codes. The only knock on exceptions is that it is slightly more overhead; but in this day and age, that overhead should be considered negligible for nearly all applications.

Here are some articles discussing, comparing and contrasting the two techniques:

There are some good links in those that can give you further reading.

Pistos
+1 for the pointers and insight.
smink
+11  A: 

In high-level stuff, exceptions; in low-level stuff, error codes.

The default behaviour of an exception is to unwind the stack and stop the program, if I'm writing a script an and I go for a key that's not in a dictionary it's probably an error, and I want the program to halt and let me know all about that.

If, however, I'm writing a piece of code which I must know the behaviour of in every possible situation, then I want error codes. Otherwise I have to know every exception that can be thrown by every line in my function to know what it will do (Read The Exception That Grounded an Airline to get an idea of how tricky this is). It's tedious and hard to write code that reacts appropriately to every situation (including the unhappy ones), but that's because writing error-free code is tedious and hard, not because you're passing error codes.

Both Raymond Chen and Joel have made some eloquent arguments against using exceptions for everything.

Tom Dunham
I found two of those posts to be very interesting (I didn't read the "and"), but particularly with Raymond's post, it was difficult to tell how much of it was truly language-agnostic. I think you could write an equally eloquent argument for using exceptions rather than error codes.
Dave DuPlantis
+1  A: 

My reasoning would be if you are writing a low-level driver that really needs performance, then use error codes. But if you're using that code in a higher-level application and it can handle a bit of overhead, then wrap that code with an interface which checks those error codes and raises exceptions.

In all other cases, exceptions are probably the way to go.

Claudiu
+2  A: 

My approach is that we can use both, i.e. Exceptions and Errors codes at the same time.

I'm used to define several types of Exceptions (ex: DataValidationException or ProcessInterruptExcepion) and inside each exception define a more detailed description of each problem.

A Simple Example in Java:

public class DataValidationException extends Exception {


    private DataValidation error;

    /**
     * 
     */
    DataValidationException(DataValidation dataValidation) {
        super();
        this.error = dataValidation;
    }


}

enum DataValidation{

    TOO_SMALL(1,"The input is too small"),

    TOO_LARGE(2,"The input is too large");


    private DataValidation(int code, String input) {
        this.input = input;
        this.code = code;
    }

    private String input;

    private int code;

}

In this way i use Exceptions to define category errors, and error codes to define more detailed info about the problem.

sakana
A: 

I may be sitting on the fence here, but...

  1. It depends on the language.
  2. Whichever model you choose, be consistent about how you use it.

In Python, use of exceptions is standard practice, and I'm quite happy to define my own exceptions. In C you don't have exceptions at all.

In C++ (in the STL at least), exceptions are typically only thrown for truly exceptional errors (I virtually never see them myself). I see no reason to do anything different in my own code. Yes it's easy to ignore return values, but C++ doesn't force you to catch exceptions either. I think you just have to get into the habit of doing it.

The code base I work on is mostly C++ and we use error codes almost everywhere, but there's one module that raises exceptions for any error, including very unexceptional ones, and all the code that uses that module is pretty horrible. But that might just be because we've mixed exceptions and error codes. The code that consistently uses error codes is much easier to work with. If our code consistently used exceptions, maybe it wouldn't be as bad. Mixing the two doesn't seem to work so well.

jrb
A: 

Exceptions are for exceptional circumstances - ie, when they are not part of the normal flow of the code.

It's quite legitimate to mix Exceptions and error codes, where error codes represent the status of something, rather than an error in the running of the code per se (e.g. checking the return code from a child process).

But when an exceptional circumstance occurs I believe Exceptions are the most expressive model.

There are cases where you might prefer, or have, to use error codes in place of Exceptions, and these have been adequately covered already (other than other obvious constrains such as compiler support).

But going in the other direction, using Exceptions allows you to build even higher level abstractions to your error handling, that can make your code even more expressive and natural. I would highly recommend reading this excellent, yet underrated, article by C++ expert Andrei Alexandrescu on the subject of what he calls, "Enforcements": http://www.ddj.com/cpp/184403864. Although it's a C++ article the principles are generally applicable, and I have translated the enforcements concept to C# quite successfully.

Phil Nash
A: 

I would never mix the two models.. it's too hard to convert from one to the other as you move from one part of the stack which is using error codes, to a higher piece that is using exceptions.

Exceptions are for "anything that stops or inhibits the method or subroutine from doing what you asked it to do" ... NOT to pass messages back abot irregularities or unusual circumstances, or the state of the system.. etc. Use return values or by reference (or out) parameters for that.

Exceptions allow methods to be written (and utilized) with semantics that are dependant on the method's function, i.e. a method that returns an Employeee object or List of Employees can be typed to do just that, and you can utilize it by calling.

Employee EmpOfMonth = GetEmployeeOfTheMonth();

With error codes, all methods return an error code, so, for those that need to return something else to be used by the calling code, you have to pass a reference variable to be populated with that data, and test the return value for the error code, and handle it, on every function or method call.

Employee EmpOfMonth; 
if (getEmployeeOfTheMonth(ref EmpOfMonth) == ERROR)
    // code to Handle the error here

If you code so that each method does one and only one simple thing, then you should throw an exception whenever the method cannot accomplish the method's desired objective. Exceptions are much richer and easier to use in this way than error codes. Your code is much cleaner - The standard flow of the "normal" code path can be devoted strictly to the case where the method IS able to accomplish what you wanted it to do... And then the code to clean up, or handle the "exceptional" circumstances when something bad happens thar prevents the method from completing successfully can be siloed away from the normal code. Additionally, if you can't handle the exception where it occurred, and must pass it up the stack to a UI, (or worse, across the wire from a mid-tier component to a UI), then with exception model, you don;t need to code every intervening method in your stack to recognize and pass the exception up the stack... The exception model does this for you automagically.... With error codes, this piece of the puzzle can get onerous very rapidly.

Charles Bretana
A: 

Since I work with C++, and have RAII to make them safe to use, I use exceptions almost exclusively. It pulls error handling out of the normal program flow and makes the intent more clear.

I do leave exceptions for exceptional circumstances though. If I'm expecting that a certain error is going to happen a lot I'll check that the operation will succeed before performing it, or call a version of the function that uses error codes instead (Like TryParse())

Eclipse