基于SQL异常代码的自定义错误消息

时间:2014-03-11 18:29:26

标签: asp.net sql vb.net exception-handling sqlexception

捕获SQL异常代码然后使用它生成自定义错误消息的最佳方法是什么?

我有一个登录页面,它填写自定义连接字符串,然后重定向到使用所述连接访问数据库的页面。在该页面上,它可能会抛出错误,具体取决于我是否输入了正确的登录信息,或者输入的数据库是否错误。

我可以在到达该页面之前测试连接,还是可以捕获异常代码并将其恢复到登录页面?

2 个答案:

答案 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)
        {
        }
    }

Exception handling

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