views:

143

answers:

6

In my vb.net application if I have a known set of Error Strings i.e.

  • Failed because I don't know about it
  • Failed because I know about it but I can't find it
  • Failed for another reason
  • etc

And I get a response which I want to ensure doesn't have the error string in it

If returnedString.equals("Failed because I don't know about it") then 
    'do something'
End if

How would people best suggest I get away from hardcoding the error string.

Ideally a enumeration could have been be used here but wouldn't work in comparing the returned error string. (please correct me if I am wrong on this!)

Are these best held as strings in the resource file or is best to have an ErrorClass with shared public propertys for each error string and check

If returnedErrorString.equals(ErrorClass.UnknownString) then 
        'do something'
End if

Or is there any other (better?) way to do this?

EDIT: The Exception suggestions I think would not be best in this situation as the returned error code doesn't necessarily cause the application to fail but will perhaps alter program flow as in what to display to the user and I have to look at the error strings as these are out with my control and returned from an external application

+3  A: 

I would say that the preferred way would be not to use error strings, but rather to create custom Exception classes for the different, um, exceptions:

UnknownException
NotFoundException
OtherReasonException

Then you have a type-safe way of determining the error cause, that is also disconnected from problems with translated text and similar.

MSDN has an article on how to create user-defined exceptions.

Fredrik Mörk
I support the Exceptions route, but this only moves the described problem to the place where the error string (from the external application) is mapped to an exception.I think the vb equivalent of a switch should do the trick there.
borisCallens
+1  A: 

You can use resources to store your strings.

You can name those resource files according to your classification:

IOErrors.resx

DBErrors.resx

FormatErrors.resx

etc.

Then you simply and elegantly reference them in your project, for example:

Resources.FormatErrors.WrongDateFormat
Developer Art
+2  A: 

Using strings to indicate error conditions, whether they are actual exceptional cases or not, is error prone in and of itself. If you must do it this way, one thing to watch out for when doing string comparisons like this is that they are case sensitive so you should probably use String.Compare(string, string, StringComparison) rather than equality.

Since the error strings are from an external application (which I take to mean you don't have any control over them), the best option would be to wrap the calls to that external application so you can encapsulate the "error handling" (i.e., the string evaluation) and either throw exceptions as appropriate or return some sort of error "code" (handled through an enum).

If the error conditions themselves don't represent actual exceptional cases, you are most likely using them to control program flow in which case you don't want to throw exceptions. Keep in mind that while throwing an exception is not expensive, catching one. Otherwise, you should consider throwing exceptions, preferably by using an existing .NET exception that meets the description of the error. If you can't find one you should create custom exceptions.

As far as the resource strings themselves, it is probably the best idea to store the actual text in a resource file. This allows you the ability (at some later point) to be able to more easily localize the text, allows you a single storage location, and provides a strongly typed class to access the string.

Scott Dorman
+1  A: 

In my 30+ years of experience, it has always been a mistake to look at error strings to determine programatically what went wrong. What if the punctuation changes?

I agree with the suggestion to use custom exceptions, but I would only create a single custom exception. I would define an enum for the reason:

public enum ExceptionReason {
    Unknown,
    NotFound
}

I would give your custom exception a property of this enum type.

For the case of "something else", just throw the existing Exception class. In fact, you'll like find out about "something else" through an exception, in which case, don't catch it - just let it pass up.

John Saunders
You should add an item - "Other" to the enum to make it sufficient for the OP's purpose. +1 for reading my mind! :P
Cerebrus
Why exactly give the exception a property rather then making custom exceptions?
borisCallens
@boris: 1) much more efficient to check the value of a property than checking the type of the exception instance in the catch clause; 2) Properly implementing exceptions takes quite a bit of boilerplate code, for serialization, implementing all the overloads, etc. Best to only do it once.
John Saunders
@Cerebrus: I suggested not using the custom exception in the "something else" case, but rather just `System.Exception`.
John Saunders
The exception classes are a much cleaner route than using an enum.
Bryan Rowe
@Bryan: how cleaner? Also, how many lines of code do each of your exception classes take?
John Saunders
A: 

I would use an enumerated list of Error codes, instead. Relying on string comparison is very prone to pitfalls (such as case sensitivity, multi-lingual issues, etc).

I was about to post an example enum (almost identical to the one @John posted), but his example seems sufficient.

Cerebrus
A: 

I agree with the above comments - however, if you must compare, then create a named constant for the string, and compare to the constant. That way if you change your error string then the code will not break.

Larry Watanabe