Когда регистрировать ошибки в ASPX при использовании соединений с базой данных? - PullRequest
0 голосов
/ 02 октября 2009

Когда регистрировать ошибки в ASPX при использовании соединений с базой данных? В следующем коде авторы Pro ASP.NET 3.5 в C # 2008 (третье издание) предлагают записать ошибку SQL в блоке catch. Мои вопросы:

Это обычная практика?

Это лучшая практика?

Короче, было бы лучше закрыть текущее соединение и обработать ошибку полностью отдельно? Каковы преимущества и недостатки любого из этих подходов?

Отредактировано, чтобы добавить: Чтобы уточнить вопрос не ЕСЛИ надо регистрироваться (этот вопрос уже обсуждался в другом месте), этот вопрос более конкретен. Вопрос в том, где в коде войти. Должно ли это быть сделано в перехвате (пока соединение еще открыто) или текущее соединение должно быть закрыто, а запись в журнал полностью отделена? Не раздел для добавления регистрации как части перехвата (даже если он вызывает внешний метод, это соединение остается открытым), пока не вернется и не достигнет «наконец».

    public int InsertEmployee(EmployeeDetails emp)
    {
        SqlConnection con = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand("InsertEmployee", con);
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add(new SqlParameter("@FirstName", SqlDbType.NVarChar, 10));
        cmd.Parameters["@FirstName"].Value = emp.FirstName;
        cmd.Parameters.Add(new SqlParameter("@LastName", SqlDbType.NVarChar, 20));
        cmd.Parameters["@LastName"].Value = emp.LastName;
        cmd.Parameters.Add(new SqlParameter("@TitleOfCourtesy", SqlDbType.NVarChar, 25));
        cmd.Parameters["@TitleOfCourtesy"].Value = emp.TitleOfCourtesy;
        cmd.Parameters.Add(new SqlParameter("@EmployeeID", SqlDbType.Int, 4));
        cmd.Parameters["@EmployeeID"].Direction = ParameterDirection.Output;

        try 
        {
            con.Open();
            cmd.ExecuteNonQuery();
            return (int)cmd.Parameters["@EmployeeID"].Value;
        }
        catch (SqlException err) 
        {
            // Replace the error with something less specific.
            // You could also log the error now.
            throw new ApplicationException("Data error.");
        }
        finally 
        {
            con.Close();            
        }
    }

Ответы [ 4 ]

0 голосов
/ 02 октября 2009

Чтобы разделить проблемы, вам нужно вытащить обработку ошибок из этого метода. Есть 3 способа сделать это:

1) (наименее элегантный) Используйте два метода:

public void InsertEmployee(EmployeeDetails emp)
{
    ...
}

public void TryInsertEmployee(EmployeeDetails emp)
{
    try
    {
        InsertEmployee(emp);
    }
    catch (Exception e)
    {
        logger.Error(e);
        throw new ApplicationException("Data error.");
    }
}

2) Используйте шаблон декоратора.

public class ErrorHandlingEmployeeGateway
{
    ...
}

3) Использовать AOP

[LogException]
public void InsertEmployee(EmployeeDetails emp)
{
    ...
}
0 голосов
/ 02 октября 2009

ИМХО это плохой совет.

Предположим, что вы используете сырой ADO.NET, вы должны обернуть свои IDisposable объекты (например, IDbConnection) в блок использования.

Если произошло непредвиденное исключение (то есть вы ничего не можете сделать), не перехватывайте его и позвольте обработчику ошибок, например ELMAH обработать его запись.

0 голосов
/ 02 октября 2009

Краткий ответ: это зависит ...

Длинный ответ:

Регистрация действительно имеет значение, только если кто-то проверяет журналы. Если это персональный сайт, то вам может быть все равно. Однако, если это критически важное приложение, вы должны регистрировать как можно больше ошибок. Журналы ошибок не только предоставляют информацию для помощи в отладке, показывая, что вы были в коде, в котором произошла ошибка, но и журналы могут также показать вам, если ошибка возникает в определенное время суток (возможно, конфликтует с другим процессом). Однако вам необходимо помнить о дополнительных затратах, связанных с регистрацией мелких ошибок. Иногда, в зависимости от того, насколько незначительным, может быть достаточно просто показать ошибку пользователю и позволить ему решить, достаточно ли это большая сделка, чтобы связаться с вами.

У меня лично есть необработанные исключения по электронной почте. Очень легко сделать с приложениями ASP.NET, используя обработчик события Page_Error.

protected void Page_Error(object sender, EventArgs e)
{
    //Handle Error Here
}

Исключения тайм-аута и другие исключения, которые я ловлю, я обычно захожу куда-нибудь в базу данных и сохраняю их навсегда. Обычно я записываю обыденные ошибки и аудиты успеха в текстовый файл, который я храню в течение месяца или около того.

Надеюсь, это поможет.

Обновление: Я думаю, что теперь я понимаю ваш вопрос лучше. Чтобы войти в ловушку, когда соединение открыто, или войти после того, как соединение закрыто? Вероятно, у вас будет лучшая производительность, если вы войдете в систему после закрытия соединения. Тем не менее, я думаю, что простая логика и удобочитаемость стоят компромисса между регистрацией вашего улова и закрытием соединения в конечном итоге.

0 голосов
/ 02 октября 2009

Обычно я использую универсальный подход и регистрирую ЛЮБЫЕ исключения, которые действительно исключительны, и проглатываю остальные. :)

EDIT:

Полагаю, мне нужно прояснить ситуацию. Основное правило для исключений - регистрировать любые исключения, кроме тех случаев, когда имеет смысл перехватить исключение.

Пример:

В .NET 1.1 единственным типом данных, который имел TryParse (), был Double. Таким образом, для других типов данных (таких как int) имеет смысл сделать это:

try{
    int.Parse(x)
} catch (FormatException){
    //take care of invalid input
}

Я бы предложил NLog . Фантастическая библиотека журналов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...