views:

49

answers:

1

I'm writing an auditing service for some business-critical operations. The service is being implemented using the IoC pattern:

public interface IAuditWriter
{
    void WriteAction(int key, string value);
}

Because of this, I need it to raise exceptions which are not specific to the implementation.

Part of the information in the audit process includes a key which is intended to be unique. It is a current requirement of the service that it provides a check for key uniqueness as part of its auditing process. Duplicate keys are a violation of a process requirement.

Currently, the service is to be implemented as a write to a SQL-Server. Although unlikely, it's possible the key might be a duplicate, in which case a SqlException will be thrown complaining about a primary key constraint violation. I would rather wrap this exception in a more generic "duplicate key" exception which can be caught and then allow the process to generate a new key.

Normally, I hate to create a new exception class; there's almost always a suitable type available that can be used to convey the same information. I have caught the System.Data.Linq.DuplicateKeyException in the past, which looked like a good candidate to throw here, except that it comes from a LINQ-related namespace, and my interface has nothing to do with LINQ.

My immediate options seem to be:

  • Throw System.Data.Linq.DuplicateKeyException anyway and hope nobody reads into the namespace too much.
  • Throw System.InvalidOperationException and cross my fingers I never need an implementation that can throw this exception for other reasons.
  • Throw my own custom DuplicateKeyException.
  • Create a separate method in the interface to check for key uniqueness and call this before I write the key and value.

What are your opinions on this?

+1  A: 

Re-using an exception from another Namespace At times I will borrow exceptions that exist in the base .NET framework but I think there should be line drawn. Personally reaching into the LINQ namespace just to re-use an exception crosses that line, I wouldn't do it.

Use InvalidOperationException That's a reasonable one to use if it seems highly unlikely that specifically catching the reason for the exception would be needed. This is not the case here so I wouldn't do that either.

Use a Custom DuplicateKeyException This makes sense. Such an exception is a likely candidate for catching, since its quite possible the code may be able to do something about it. The exception comes from your namespace and you could add other relevant details to aid the exception handling.

Add a "IsUnique" method What happens if between calling "IsUnique" and your WriteAction method the key ceases to be unique, say due to another thread changing things? This method may be useful since without it code may rely on exceptions being thrown to detect it (which would be a bad thing). However you still need to create an exception if on WriteAction the key turns out not to be unique, there's no guarantee the consumer of the interface will even call the "IsUnique" method first.

AnthonyWJones
A good answer, thanks. By process of elimination of the sucky alternatives, I think a custom exception is the inevitable best option here.
Programming Hero