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 FaileddalException =
new DalLoginException(ex.Message, ex); break; case 547: // ForeignKey ViolationdalException =
new DalForeignKeyException(ex.Message, ex); break; case 1205: // DeadLock VictimdalException =
new DalDeadLockException(ex.Message, ex); break; case 2627: case 2601: // Unique Index/Constriant ViolationdalException =
new DalUniqueConstraintException(ex.Message, ex); break; default: // throw a general DAL ExceptiondalException =
new DalException(ex.Message, ex); break;}
}
// return the error return dalException;}
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){
}
Alef,
We're having some weird exception issues and I am curious to know how you solved your issue.
Thanks,
John
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