views:

99

answers:

1

I am interested to see how other people have implemented flexible error handling. I will explain what I need specifically.

We all know that we can use exception wrapping (and catch it later where needed). However, what I would like to implement (and elegantly) is distinguishing the types of errors after the stored proc is invoked.

I have p_error field where stored proc dumps its errors. It could be validation error(where validating against DB can't be avoided), or authorization error (we do that in 2 places, one of which is DB), or a SQL error.
In short I need a pretty and elegant mechanism to distinguish between the type of error before throwing an exception.

Two approaches I thought of: 1) On the database level have 3 error fields: 1 for authorization, 1 for SQL error and 1 for any other errors. This could get hairy.

2) Creating an error struct (enum?) where error messages are stored and later can be compared against. Again, too wordy. what if a error message in db changes...to hard to maintain.

Any other ideas?

A: 

I don't see why people keep doing this p_error nonsense. At least with oracle (and I'm quite sure with sql server as well) the result of calling a stored procedure which throws an exception is a raised exception which contains far more information than this silly p_error field possibly can.

Again, my recent experience is simply with oracle but I would write a wrapper for all stored procedure calls (standard practice anyways) and inside it do something like this

try {
  RunMyStoredProcedure();
}
catch(OracleException e) {
  new OracleExceptionProcessor().HandleException(e);
}
//...
//...
class OracleExceptionProcessor {
  static List<int> _validationErrorCodes = new List<int> { 123, 456};
  static List<int> _authenticationErrorCodes = new List<int> { 789};

  public void HandleException(OracleException ex) {
    if(_validationErrorCodes.Any(c==ex.ErrorCode))
      throw new DatabaseValidationError(ex);
    if(_authenticationErrorCodes.Any(c==ex.ErrorCode))
      throw new DatabaseAuthenticationError(ex);
    throw new DatabaseSQLError(ex);
  }
}

Since I can't imagine the database having all that many validation or authentication error codes this should be pretty simple and easy.

George Mauer
Thanks. I'm going to be more clear. There are 2 types of errors: trapped on the application level actually I am obliged to use a wrapper class that deals with Oracle, it throws its own exceptions, which I catch.
gnomixa
But your idea is to basically use error codes to distinguish the error types. Question: are these custom codes?
gnomixa
Catching errors inside database I (and many others) consider very bad form. I assume that you roll back inside the SP? That should be the responsibility of the calling application. When I _have_ to do this, I always re-throw the exception. You can still do my approach if you can retrieve error code
George Mauer
Oh, no, I just made up some numbers because I didn't feel like looking it up. I trust that you can do that part ;)
George Mauer
yes i roll back inside the SP. I don't want to discuss why something is bad/good. There are always 100 ways to do the same thing - the point is I have to stick with these circumstances.
gnomixa
Thats fair, can you re-throw the exception? If not you need to figure out some way to get at the parts of it that are important to you. You could include a p_error_code or give p_error a custom format something like "{ErrorCode} - Message" that you can parse.
George Mauer
Yes, I can re-throw it. That's not the point though. From the database I get several types of errors (validation, authorization etc). Before I re-throw it, I NEED TO KNOW WHICH ONE IT IS so I can handle it differently. Authorization error should result in redirecting to a non-auth page, for example.
gnomixa
While validation error should just be presented to the user. The only way to differentiate TYPES of errors, i thought, was to have a Error struct/class/enum where I store custom error code/message and parse it after. But then it can get hairy. Alternatives?
gnomixa
Hope I am finally being clear.
gnomixa
I think you get what I'm saying - use the error code. I think that is by far the best solution given your constraints and what exactly is the problem with doing it the way I specified?The rethrow that I refer to would come from the SP, but it is not necessary as long as you can get the code.
George Mauer