views:

124

answers:

4

Recently I'm refactoring a .net program which will use a custom usb device. The device comes with a dll for communication. The dll is written in c and by checking the header, it defines a set of error return codes.

The first step to comminicate with the device is to open the device.

In dll, the open function looks like this:

// return different codes, such as OK, ERROR_CANNOT_CLAIM_INTERFACE, etc.  
int DLL_Open();

In the .net program, it's using exception for error code:

// Return true if succeed. Throw exception if there is error.
bool Open()
{
    int flag = DLL_Open();
    if(flag == OK) return true;
    else
    {
        if(flag == ERROR_CANNOT_CLAIM_INTERFACE)
            throw USBException();
        // ...
    }
}

My question is, why to use exception instead of simply using error codes as the dll API? I read some articles mentioned "Don't use exception to control application flow", and I think the exception here is kind like controlling the flow.

A: 

A return code doesn't affect the flow of execution. You're at liberty to ignore a return code, whereas an exception has to be actively caught and disregarded.

I would make use of exceptions where something sufficiently bad has happened such that you can't carry on using that component (or sub-component etc.) without some remedial action - in this case plugging a USB stick in.

Is this controlling program flow ? Obviously yes (as is any exception). But a valid question is how exceptional is this ?

Brian Agnew
A: 

Exception are a decent way of handling errors, you could user other forms (Ex: GOTO ), but it is not good. I also don't agree with the idea of not using it do control flow... Obviously, the flow I am talking about is a very low intrusion flow, you should aline zilions of decisions all based on exception, but you can define different action and flows depending on certain kinds of exception. Also is a good way of bubbling up errors.

Oakcool
A: 

Both solutions work, with enums providing better performance and exceptions potentially providing better decoupling (across system boundaries). It's actually a matter of software design and conventions. Basically use exceptions if the functional scope of the system you're working on does not include handling the given error condition.

If this .NET program has its own UI, you don't need to throw an exception. Use enums and display an error to the user. On the other hand, if this .NET program is an assembly to be used by third parties, it's considered more conventional to not expose error codes or enums in the API, and instead to throw (and document) exceptions.

The middle ground would be that this program doesn't have it's own UI but it's consumed by another system that you also (or someone in your organization) has control over. In that case you can go either way, with enums providing better performance, and exceptions providing better decoupling.

gWiz
A: 

It comes down to a very simple question: Is it typical program flow for this to occur?

You don't want the standard conditional logic of your code being controlled by exceptions, but on the other hand if it's a real error-case then throwing an appropriately typed exception is the best way to go. It really does come down to whether the event is an expected outcome of calling the function or a rare edge-case error. Sometimes it even makes sense to do both, expose the expected outcomes as an enum but still put the real errors down as exceptions.

From a performance perspective, the exception model uses drastically more processing power but only when the exception is thrown. If there's no error it's actually faster than using an enum. If you really want to look into this performance then looking for info on Int32.Parse vs Int32.TryParse probably has the most information out there (The first used the exception model and they added the second to improve performance cause people were regularly using it on unvalidated data).

Tim Schneider