Create my own exceptions

Create my own exceptions

Old forum URL: forums.lhotka.net/forums/t/5973.aspx


alef posted on Wednesday, December 10, 2008

When a database error occurs in the dal layer I want to translate it for certain errors to my own exceptions. Is there a central place where I can call my method TranslateException? I don't want to do this in the UI because the UI must be agnostic for which type of database we are using (sqlexception, oracleexception).

/// <summary>

/// Translate a SqlException to the correct DALException

/// </summary>

/// <param name="ex">SqlException to be translated</param>

/// <returns>An DALException</returns>

protected Exception TranslateException(SqlException ex) {

Exception dalException = null;

// Return the first Custom exception thrown by a RAISERROR

foreach (SqlError error in ex.Errors) {

if (error.Number >= 50000) {

dalException = new DalException(error.Message, ex);

}

}

if (dalException == null) {

// uses SQLServer 2000 ErrorCodes

switch (ex.Number) {

case 17:

// SQL Server does not exist or access denied.

case 4060:

// Invalid Database

case 18456:

// Login Failed

dalException = new DalLoginException(ex.Message, ex);

break;

case 547:

// ForeignKey Violation

dalException = new DalForeignKeyException(ex.Message, ex);

break;

case 1205:

// DeadLock Victim

dalException = new DalDeadLockException(ex.Message, ex);

break;

case 2627:

case 2601:

// Unique Index/Constriant Violation

dalException = new DalUniqueConstraintException(ex.Message, ex);

break;

default:

// throw a general DAL Exception

dalException = new DalException(ex.Message, ex);

break;

}

}

// return the error

return dalException;

}

ajj3085 replied on Wednesday, December 10, 2008

You could try to do this by overriding DataPortal_OnDataPortalException, I would think, in your common base classes (you do have base classes between Csla BusinessBase and your own Business objects, right?)

alef replied on Wednesday, December 10, 2008

Override DataPortal_OnDataPortalException.  So I need to create a MyCompanyBusinessBase, and have all my classes inherit that subclass.  I believe Rocky recommends creating such a subclass even if initially it doesn't add any behavior at all, because someday you will. Apparently this day is arrived.

DataPortal_OnDataPortalException is declared as follows:

protected virtual void DataPortal_OnDataPortalException(DataPortalEventArgs e, Exception ex)

{

}


But if I replace the exception with my own dalexception, there's no way of getting this new exception type back to the DataPortal to be thrown back to the client as the return type of  DataPortal_OnDataPortalException is void and the parameter to the method is not passed by ref. 

JohnB replied on Wednesday, March 10, 2010

Alef,

We're having some weird exception issues and I am curious to know how you solved your issue.

Thanks,
John

RockfordLhotka replied on Wednesday, March 10, 2010

The data portal will always return a DataPortalException from the server. That is necessary because it is the server DataPortalException that knows how to do things like carry the server-side stack trace back to the client and merge it with the client-side stack trace.

The server-side DataPortalException carries an InnerException, which is the "real" exception that occurred on the server.

On the client, the data portal gets the server-side DataPortalException, and takes it apart, using it to create a client-side DataPortalException, which is then thrown on the client side.

The client-side DataPortalException has an InnerException, but it also has a BusinessException. The BusinessException is typically the original exception that cause the issue to start with. The InnerException may or may not be the same, depending on whether intermediate layers of code wrapped that original exception (which can happen in some cases).

In short, it is BusinessException that you typically want.

In your Save() override, you can catch the DataPortalException and throw the BusinessException if you'd like. You'll lose a bunch of useful information by doing so, because the BusinessException only has part of the server-side stack trace, etc. But you might choose to give up that information to simplify the consuming code - it will be easier to write and harder to debug.

Copyright (c) Marimer LLC