views:

196

answers:

8

Hey all,

Say you have an enum that represents an error code. There will be several codes, each with their own underlying int value; however, the enum value that gets the default 0 value seems like it should be carefully considered.

In the case of an error code enum, there are two special values that I can think of: None (for cases when there is no error) and Unknown (for cases when no existing error code is appropriate, or perhaps even when error state cannot be detected).

One of these values seems like it should get 0, where the other will probably get something else like -1. Is it more appropriate to set the None value to 0, or the Unknown value to 0?

public enum ErrorCode
{
    None = -1,
    Unknown = 0,
    InsufficientPermissions,
    ConnectivityError,
    ...
}

public enum ErrorCode
{
    Unknown = -1,
    None = 0,
    InsufficientPermissions,
    ConnectivityError,
    ...
}

My instinct tells me that the default should be Unknown, but I'm curious if anyone has done it differently.

+1  A: 

Why return an ErrorCode value at all when there is no error?

Doesn't make a whole lot of sense. Removing that would resolve your issue. You could just make 0 be for Unkown:

public enum ErrorCode
{
    Unkown = 0,
    InsufficientPermissions,
    ConnectivityError
}

UPDATE

Your comment is a little scary. You should never have a method that returns a type of ErrorCode. It's very poor practice. Since ErrorCodes should only be returned in Exceptional circumstances, it's a good idea to throw Exceptions.

If you want, you can have a field in your custom Exception that contains the ErrorCode value.

Justin Niessner
If your function's signature is `public ErrorCode DoFoo()`, what do you return when the function succeeded?
Karmastan
@Karmastan - I would never have a method that returns an ErrorCode. I would have a custom Exception that gets thrown and contains the ErrorCode inside that.
Justin Niessner
The framework uses error codes when you know an operation may fail under normal circumstances. For example, Int32.TryParse returns a value instead of throwing an exception. I also use error codes on Validation methods where I'm expecting a problem. In this case having an error isn't an exception, it is the intended use.
Jonathan Allen
Rename the enum to something less misleading to the user code. You're returning a status, not an error code. Then, remove "None" from the equation, because there's no such thing.
spoulson
+13  A: 

Since you're tagging your question with best-practices: don't use error codes when you can use exceptions.

Pontus Gagge
Another post related to this issue: [Exceptions or error codes](http://stackoverflow.com/questions/253314/exceptions-or-error-codes)
Karmastan
You can use exception and error codes to disambiguate and provide a mean to reference a specific error in documentation.
João Angelo
An error is not necessarily an exceptional occurance. The error code may be the return value of a Validate method.
Jonathan Allen
Who's to say he's not going to use error codes in an exception?
spoulson
@spoulson if he does that, then he's painting future developers into a corner in terms of being able to catch the "most specific" type of exception. The cost of creating an `InsufficientPermissionsException` and `ConnectivitiyErorrException` etc... is not prohibitive.
Michael Meadows
@Michael, I would really recommend against doing that. Imagine how many exception classes you would have to deal with if you created a separate one for every SQL, Win32, or COM exception. Also, you can use filtered exception handlers `Catch ex as ComExcetion Where ex.ErrorCode = 123456`.
Jonathan Allen
The convention in practice on this codebase is that error codes are used for known failures, and exceptions are used for situations only where processing cannot proceed. Validation is a perfect example. Also, the question had nothing to do with exceptions.
bwerks
So @bwerks, perhaps you should retag to 'least-bad-practice'...?
Pontus Gagge
The question pertains to the declaration of enums, not the ways that those enums will be used. The example I provided is anecdotal. Unless you're suggesting that usage of enums for any purpose is always bad practice, I think the tag is fine.
bwerks
+5  A: 

In my opinion both Unknown or None mean the same thing in the context of the ErrorCode enumeration. My reasoning is that if I'm checking an error code than it's because I already have an error.

I'm also of the opinion that an error code enumeration is only useful in a custom exception or as custom data of an existing exception type and in both scenarios you will always have an error.

João Angelo
This call is not up to me, sadly; however, given that these values will be persisted to a database, it makes sense to include Unknown as a means of translating to null in the database. Although, I suppose using a nullable in that case would work too.
bwerks
Why isn't the call up to you? How can you change the enum values if you do not have access to the code that catches the exceptions and returns error codes (for Unknown errors in particular)? If it is a political problem, please, for the love of justice and truth and saving money, point the powers that be to this and related SO posts so they can see that a majority of professional software developers strongly oppose returning error codes!
apollodude217
A: 

ErrorCodes bad. Exceptions good. But to answer the question as asked:

If your enum has an "Unknown" value, it should be the default.

Joel Coehoorn
First of all, error codes are often combined with exceptions. Secondly, it is polite to offer a Validate method so that the user can see what errors would occur if the attempted some action. Remeber, exceptions are expensive both in CPU time and lines of code.
Jonathan Allen
@Jonathan, I agree, except that with validation, would you really call it "ErrorCodes?" Also, typically, validation occurs at a high enough level that you can use constants (or localized strings) to represent the validation error. If it gets deep enough into your framework to require a code, then it really *is* an exceptional condition.
Michael Meadows
I used to return strings, but that made searching and filtering really hard. So now we have an error code for every scenario in addition to the strings. These aren't application errors either, these are data issues that a business user would needs to research and manually correct.
Jonathan Allen
+3  A: 

First of all, you shouldn't have a None error code. Instead, call it "Success".

Now think about how you are going to check the error code. Most people expect something like this:

if (errorCode != Success)

or they use the shorthand

if (errorCode != 0)

So there you have it. Your Success code is 0, you don't have a None code, and Unknown can be anything you want.

Jonathan Allen
A: 

Ditto to all of the "I wouldn't do it responses," but if you insist, here's my $0.02.

ErrorCodes.None makes no sense, since there's no error. ErrorCodes.Unknown is not helpful. Try returning a nullable error code:

public ErrorCode? DoFoo()

Now you can check for null

var error = DoFoo();
if (error != null)
    // react

Still bad, but at least it allows you to not return an error code if there's no error.

Michael Meadows
I disagree with this. First, FxCop tells us that we should always have a "default" value for when "the enum has not be explicitly set". So, having "Unknown" or "None" is definitely appropriate.Secondly, using a Nullable<T> or ? syntax undermines a major point of having an enum, to force the consumer to choose SOMEthing!
Robert Seder
+3  A: 

Definitely not a good practice. But if there is no other way...then I would generally go by the second option:

public enum ErrorCode 
{ 
    Unknown = -1, 
    None = 0, 
    InsufficientPermissions, 
    ConnectivityError, 
    ... 
} 

0 goes well by the convention 'No Error' and -1 goes fine with the understanding that there is some error (which may be unknown).

prabhats.net
Thanks for answering the question based on convention, and not getting distracted by how crappy it is.
bwerks
+4  A: 

I guess I'll disagree with everyone else on this.

There's nothing wrong with error codes when used in the sense of "what is the current state of this feature."

To make up an example: if you have an optional networked temp folder, that you want to access, and you want to display the results from the most recent time that you attempted to access it, you would save that in an error code. Perhaps on a status bar you want to show the current state to the user.

For me, I would use None as 0, as the default. I see no reason to make Unknown be negative. Unknown is a perfectly fine error state. You can just put it at the end of the list. In practice, I have done

public enum ErrorCode
{
    None = 0,
    InsufficientPermissions,
    ConnectivityError,
    ...
    Unknown,
}

And to answer your question, I say None must be the default. None means: no error exists that you are aware of. Unknown would mean to me: an error exists that is so obscure that you can't account for it in your code.

Detmar