捕获SQL异常代码然后使用它生成自定义错误消息的最佳方法是什么?
我有一个登录页面,它填写自定义连接字符串,然后重定向到使用所述连接访问数据库的页面。在该页面上,它可能会抛出错误,具体取决于我是否输入了正确的登录信息,或者输入的数据库是否错误。
我可以在到达该页面之前测试连接,还是可以捕获异常代码并将其恢复到登录页面?
答案 0 :(得分:3)
这个问题实际上是广泛的。我将尝试添加图像以减少冗长的代码。我在这个例子中只考虑UniqueConstraintException
并且将使用C#而不是vb.net。不得不改变我的代码。
在我的场景中,我创建了一个继承自BaseException
类的Exception
类。
public class BaseException : Exception
{
public BaseException()
: base()
{ }
public BaseException(string _exceptionMessage)
: base(_exceptionMessage)
{
}
public BaseException(string _exceptionMessage, Exception _innerException)
: base(_exceptionMessage, _innerException)
{
}
}
由于我对SQL异常感兴趣,所以我将创建更多的类。
请参阅下面的类图,SqlHelperException
派生自BaseException类。您的CRUD operations in DAL
点击数据库将抛出SqlHelperException类对象,应该由BAL
层处理。
public class SqlHelperException : BaseException
{
public string ErrorMessage { get; set; }
public SqlHelperException()
: base()
{
}
public SqlHelperException(string message)
: base(message)
{
}
public SqlHelperException(string message, System.Exception innerException)
: base(message, innerException)
{
}
}
public class SqlHelperUniqueConstraintException : SqlHelperException
{
public SqlHelperUniqueConstraintException()
: base()
{
}
public SqlHelperUniqueConstraintException(string message)
: base(message)
{
}
public SqlHelperUniqueConstraintException(string message, Exception innerException)
: base(message, innerException)
{
}
}
完成基础工作后,我编写了一个translator which accepts SqlException
并将其包装到SqlHelperException对象中
public static SqlHelperException TranslateException(System.Data.SqlClient.SqlException ex)
{
SqlHelperException dalException = null;
// Return the first Custom exception thrown by a RAISERROR
foreach (System.Data.SqlClient.SqlError error in ex.Errors)
{
if (error.Number >= 50000)
{
dalException = new SqlHelperException(error.Message, ex);
}
}
if (dalException == null)
{
// uses SQLServer 2005 ErrorCodes
switch (ex.Number)
{
case 2601:
// Unique Index/Constriant Violation
dalException = new SqlHelperUniqueConstraintException(ex.Message, ex);
//Overwrite Error message with your custom error message, we can use Resource file
dalException.ErrorMessage = ErrorMessages.SqlHelperUniqueConstraintException;
break;
case 18456:
// Login Failed
dalException = new SqlHelperLoginException(ex.Message, ex);
break;
default:
// throw a general DAL Exception
dalException = new SqlHelperException(ex.Message, ex);
break;
}
}
// return the error
return dalException;
}
在这个翻译器中,我使用ErrorMessages.SqlHelperUniqueConstraintException
静态属性来保存实际的错误消息。
public class ErrorMessages
{
public static readonly string SqlHelperUniqueConstraintException;
static ErrorMessages()
{
SqlHelperUniqueConstraintException = "{0} failed, duplicate {1} already exists.";
}
}
现在在我编写CRUD操作的DAL层中,我只是消耗了这些异常
public class Person
{
public void Create()
{
SqlHelper sql = new SqlHelper();
try
{
sql.ExecuteNonQuery()
}
catch (SqlEception ex)
{
var e =TranslateException(ex);
e.ErrorMessage = string.Format(e.ErrorMessage, "Creation", "Person");
throw e;
}
}
}
通过这样做,在BAL我会收到错误消息:"创建失败!重复的人已经存在。"
答案 1 :(得分:0)
我最终做的只是“尝试”打开连接,如果失败,请抓住异常消息,并将其放在页面上的标签上。
Dim queryString As String = "LOGINPROPERTY ( '" + Username + "' , 'property_name' )"
Dim connection As New SqlConnection(ConnectionString)
Dim command As New SqlCommand(queryString, connection)
Try
connection.Open()
Response.Redirect("destination.aspx")
Catch ex As Exception
LabelError.Text = ex.Message
Finally
End Try