Does somebody know how to display a user friendely message if SQL server encounters a duplicate key exception like the following :
Type : Csla.DataPortalException, Csla, Version=3.5.2.0, Culture=neutral, PublicKeyToken=93be5fdc093e4c30
Message : DataPortal.Update mislukt (System.Data.SqlClient.SqlException: Cannot insert duplicate key row in object 'dbo.Look' with unique index 'UNIQUE_LookValue_Per_LookTypeFID'.
The statement has been terminated.
bij System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
bij System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
bij System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
bij System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
bij System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
bij System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
bij System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
bij System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
bij System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
bij Shoesoft.Library.Hoofdafdeling.ExecuteInsert(SqlConnection cn) in D:\Projects\DOTNET\Shoesoft\Shoesoft.Library\Admin\Hoofdafdeling.Generated.cs:regel 203
bij Shoesoft.Library.Hoofdafdeling.DataPortal_Insert() in D:\Projects\DOTNET\Shoesoft\Shoesoft.Library\Admin\Hoofdafdeling.Generated.cs:regel 186
bij dm(Object , Object[] )
bij Csla.Reflection.MethodCaller.CallMethod(Object obj, DynamicMethodHandle methodHandle, Object[] parameters) in D:\Projects\DOTNET\csla\cslacs\Csla\Reflection\MethodCaller.cs:regel 221)
You have to wrap your Save inside try/catch in UI and examine
the error text of the message, looking for specifics. If you find those,
display a friendly message, otherwise just re-throw the exception.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: alef
[mailto:cslanet@lhotka.net]
Sent: Saturday, November 22, 2008 10:37 AM
To: Sergey Barskiy
Subject: [CSLA .NET] How to display a user friendly message for the user
Does somebody know how to display a user friendely message if SQL server
encounters a duplicate key exception like the following :
Type : Csla.DataPortalException, Csla, Version=3.5.2.0, Culture=neutral,
PublicKeyToken=93be5fdc093e4c30
Message : DataPortal.Update mislukt (System.Data.SqlClient.SqlException: Cannot
insert duplicate key row in object 'dbo.Look' with unique index
'UNIQUE_LookValue_Per_LookTypeFID'.
The statement has been terminated.
bij System.Data.SqlClient.SqlConnection.OnError(SqlException
exception, Boolean breakConnection)
bij
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception,
Boolean breakConnection)
bij
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject
stateObj)
bij System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,
SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet
bulkCopyHandler, TdsParserStateObject stateObj)
bij System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader
ds, RunBehavior runBehavior, String resetOptionsString)
bij
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
bij System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method,
DbAsyncResult result)
bij
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result,
String methodName, Boolean sendToPipe)
bij System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
bij Shoesoft.Library.Hoofdafdeling.ExecuteInsert(SqlConnection cn)
in
D:\Projects\DOTNET\Shoesoft\Shoesoft.Library\Admin\Hoofdafdeling.Generated.cs:regel
203
bij Shoesoft.Library.Hoofdafdeling.DataPortal_Insert() in
D:\Projects\DOTNET\Shoesoft\Shoesoft.Library\Admin\Hoofdafdeling.Generated.cs:regel
186
bij dm(Object , Object[] )
bij Csla.Reflection.MethodCaller.CallMethod(Object obj,
DynamicMethodHandle methodHandle, Object[] parameters) in
D:\Projects\DOTNET\csla\cslacs\Csla\Reflection\MethodCaller.cs:regel 221)
I have a static method to handle exceptions. Looks something like this (I removed application specific code and calls to methods which log exceptions in the database for further investigation):
try
{
// Do some BO work here
}
catch (Exception ex)
{
string Message = BusinessObjects.Common.ExceptionHandling.HandleException("Some custom message here regarding the context of where the error is happening", ex);
MessageBox.Show(Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
public static string HandleException(string userInformation, Exception ex)
{
// Check to see if the exception is from the DataPortal (to search for any SQL exceptions)
if (ex.GetType() == typeof(DataPortalException))
{
DataPortalException LocalEx = (DataPortalException) ex;
Exception LoopException = LocalEx;
Exception SqlException = null;
// Loop all inner exceptions to see if we got a SqlClient exception
while (LoopException != null)
{
if (LoopException.Source == ".Net SqlClient Data Provider")
{
SqlException = LoopException;
break;
}
// Get next inner exception
LoopException = LoopException.InnerException;
}
// If Sql server error message then only show the message from sql server
if (SqlException != null)
userInformation = string.Format("{0}", SqlException.Message);
else
{
userInformation += Environment.NewLine + Environment.NewLine + ex.Message;
}
}
else if (ex.GetType() == typeof(ValidationException)) {
userInformation = "Validation error. Please check values.";
}
else
{
userInformation += Environment.NewLine + Environment.NewLine + ex.Message;
}
return userInformation;
}
You could actually do this in SQL server, although I am not sure
if this is worth the effort either. You could wrap your SP in try/catch
blocks, trap excepti9ons that can occur, and Raise a custom error. This is
a lot of work though.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: dagware
[mailto:cslanet@lhotka.net]
Sent: Sunday, November 23, 2008 12:56 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] How to display a user friendly message for the
user
The following isn't always possible, and I suppose there are
even times when it's not worth the effort, but just in case you haven't thought
about it (and please forgive me if I'm being patronizing):
Consider coding your business objects to detect this type of error before you
do the save, typically when a new object is added to the list. This is
often-times done with an "ExistsCommand" type of command object
(ProjectTracker has these, but I don't know if it actually uses them or not).
Of course, even with due diligence you could still get the error, for instance
if someone else added the item to the database between when you checked for its
existence and when you actually saved the object.
I've often wished SQL Server returned errors in a documented way that would
make it easy to parse the error into end-user-readable text. I guess I just
like to dream.
Dan
Copyright (c) Marimer LLC