Вопрос

What would be the best way to catch the SQL exception code, and then use it to produce a custom error message?

I have a login page which fills out a custom connectionstring, then redirects to a page which uses said connection to access a database. On that page, it can throw errors depending on if I entered the correct login info, or if the database entered is wrong.

Can I just test the connection before I get to that page, or can I catch the exception code and bring it back to the login page?

Это было полезно?

Решение 2

What I end up doing was just "trying" to open the connection, and if it failed, catch the exception message, and put it on a label on the page.

    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

Другие советы

This question is actually to wide. I will try to add an images to reduce lengthy code. I am considering only UniqueConstraintException in this example and will use C# instead of vb.net. Have to change my lot of code otherwise.

In my scenario, I created a BaseException class which is inherited from Exception class.

public class BaseException : Exception
{
    public BaseException()
        : base()
    { }

    public BaseException(string _exceptionMessage)
        : base(_exceptionMessage)
    {
    }

    public BaseException(string _exceptionMessage, Exception _innerException)
        : base(_exceptionMessage, _innerException)
    {
    }
}

Since I am interested SQL exceptions so I will create few more classes.

See my class diagram below, SqlHelperException is derived from BaseException class. SqlHelperException class object will be thrown by your CRUD operations in DAL hitting database, should be handled by BAL layer.

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

Once my ground work is done, I wrote a translator which accepts SqlException and wraps it into SqlHelperException object

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;
        } 

Here in this translator, I used ErrorMessages.SqlHelperUniqueConstraintException static property which holds actual error message.

public class ErrorMessages
    {
     public static readonly string SqlHelperUniqueConstraintException;
     static ErrorMessages()
        {
            SqlHelperUniqueConstraintException = "{0} failed, duplicate {1}  already exists.";
        }
    }

Now in my DAL layer where I wrote my CRUD operations, I simply consumed these exceptions

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;
            }
        }
}

By doing so, at BAL I will get error message saying : "Creation failed! duplicate person already exist."

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top