Почему я не получаю трассировку исключения на странице перенаправления ошибок?

В своем стремлении реализовать лучшие методы обработки пользовательских ошибок я пришел к идее не использовать try catch где-либо в моем коде. Вместо этого я решил использовать customErrors mode = "On" и перенаправить на страницу ошибок и показать подробности исключения на этой странице.

//My test code from which error will come
public ActionResult Index()
    { 
        AAA aa = null;
        aa.a = "a"; 
    }

//My web.config file
 <customErrors mode="On" defaultRedirect="~/Errors/Error.aspx">
  <error statusCode="404" redirect="~/Errors/404.html" />
</customErrors>

//My error handling page(Error.aspx):
 protected void Page_Load(object sender, EventArgs e)
    {
        Exception error;
        error = Server.GetLastError();            
    }

Я считаю, что на моей странице обработки ошибок должно появиться сообщение об ошибке. Но я всегда получаю ноль.

Как мне получить сообщение об исключении на странице обработки ошибок?


person CodesDDecodes    schedule 20.06.2019    source источник
comment
Вы используете Asp.Net MVC (или) Asp.Net?   -  person Rahul    schedule 20.06.2019
comment
его asp.net mvc, но для страницы ошибки я использую файл .aspx   -  person CodesDDecodes    schedule 20.06.2019
comment
Этот код ничего не отображает. Он просто сохраняет исключение в локальной переменной   -  person Panagiotis Kanavos    schedule 20.06.2019
comment
хорошо, я получаю null в ошибке локальной переменной, и мне нужно исключение, которое было поднято в общедоступном ActionResult Index () в этой локальной переменной.   -  person CodesDDecodes    schedule 20.06.2019
comment
Это далеко не лучшая практика.   -  person Chris Pickford    schedule 20.06.2019
comment
Возможный дубликат страницы настраиваемой страницы ошибок ASP.NET - Server.GetLastError ( ) имеет значение null   -  person Chris Pickford    schedule 20.06.2019
comment
Проверьте Пользовательские страницы ошибок в ASP.NET MVC. Легко, правда?. Использование redirectMode="ResponseRewrite" - лишь одно из требований   -  person Panagiotis Kanavos    schedule 20.06.2019
comment
добавлен redirectMode = ResponseRewrite, и я ожидал System.NullReferenceException: «Ссылка на объект не установлена ​​на экземпляр объекта». в Server.GetLastError (), но я получил Представление «Ошибка» или его мастер не найден, либо механизм представления не поддерживает найденные местоположения. Был произведен поиск в следующих местах: ~ / Views / Home / Error.aspx ~ / Views / Home / Error.ascx ~ / Views / Shared / Error.aspx ~ / Views / Shared / Error.ascx ~ / Views / Home / Error. cshtml ~ / Views / Home / Error.vbhtml ~ / Views / Shared / Error.cshtml ~ / Views / Shared / Error.vbhtml в ошибке   -  person CodesDDecodes    schedule 20.06.2019
comment
Крис, я хотел бы изучить передовой опыт, если вы можете что-нибудь посоветовать ...   -  person CodesDDecodes    schedule 20.06.2019
comment
@CodesDDecodes, с другой стороны, вы можете указать любую страницу, которую хотите, в самом MVC, например, app.UseExceptionHandler("/Home/Error");, как показано в этом вопросе   -  person Panagiotis Kanavos    schedule 20.06.2019
comment
Лучшая практика обработки исключений - это обработка ваших исключений. В случае, если произойдет что-то неожиданное, вам следует написать глобальный обработчик исключений, чтобы зарегистрировать проблему и представить что-то удобное для пользователя.   -  person Chris Pickford    schedule 20.06.2019
comment
@CodesDDecodes, что касается лучших практик, там только один - don't follow blindly "best practices" without understanding what they mean, what they are for and what they are *not* for. Не используйте слепо код, который выглядит актуальным - это следствие. Исключения следует ловить там, где с ними можно работать. Если вы правильно напишете свои методы, ограничивая побочные эффекты, вам, возможно, придется обрабатывать исключения только на верхнем уровне. Однако то, что вы там делаете, зависит от типа исключения, типа приложения, метода, пользователей, требований к поддержке.   -  person Panagiotis Kanavos    schedule 20.06.2019
comment
Например, вы не можете отобразить страницу 500 пользователю, редактирующему сетку. Инженерам службы поддержки нужны журналы с достаточной информацией, чтобы они могли решать проблемы. Им не нужны стеки исключений, им нужна запись журнала, в которой указано Product ID XYZ not found in the database или Database didn't respond. Разработчикам, с другой стороны, требуются совсем другие журналы с полной информацией.   -  person Panagiotis Kanavos    schedule 20.06.2019


Ответы (1)


Позвольте мне пролить свет на то, как я обычно обрабатываю исключения в проектах, над которыми работаю. Но давайте разберемся на разделы.

Страницы ошибок

Страницы ошибок не должны показывать настоящее исключение в рабочей среде. Пользователю не нужно знать, что в базе данных произошел сбой, который может подвергнуть вашу систему проблемам безопасности. Страница с общей ошибкой или хорошо документированным кодом ошибки подойдет. Но, конечно, в вашей среде разработки можно показывать исключения. Я бы посоветовал использовать customErrors mode="RemoteOnly" в этом случае.

Код ошибки

В зависимости от системы, которую вы разрабатываете, было бы важно иметь в сообщении код ошибки. Например, пользователь мог увидеть «Невозможно подключиться (XYZ_1234)» или «Не удалось подключиться (ABC_9876)» - то же сообщение, разные коды - и отправить его на группа поддержки. Если у службы поддержки есть документ, соответствующий кодам с реальными исключениями, они смогут отправить разработчикам соответствующий отчет.

Блоки Try / Catch

Try / Catch - ваш лучший друг, когда дело касается исключения. Тем более, что это поможет вам при необходимости настроить исключение. У вас может быть ряд настраиваемых классов исключений - каждый со своей характеристикой, - которые помогут вам узнать о проблеме еще до отладки. Один простой пример:

public class ExceptionWithCode : Exception
{
    public ExceptionWithCode(string code, string message) : base(message)
    {
        this.Code = code;
    }

    public string Code { get; }
}

В коде вы должны подходить к этому примерно так:

try
{
    // Do whatever database operation here
}
catch (SqlException ex)
{
    // Log the exception
    _logService.Log(ex);

    // Throw something else to the user
    throw new ExceptionWithCode("XYZ_1234", "Unable to connect");
}
catch (Exception ex)
{
    // Log the exception
    _logService.Log(ex);

    // Throw something else to the user
    throw new ExceptionWithCode("ABC_9876", "Unable to connect");
}

Обратите внимание, что я использую 2 защелки. Во-первых, я знаю, что это исключение может произойти, поскольку я подключаюсь к БД, а во-вторых, на случай, если может произойти что-то еще. Кроме того, пользователь не знает настоящего исключения, поскольку он / она получает просто случайное исключение с кодом вместо сбоя соединения с базой данных.

Журналы

Это очень важная часть. Помните: Вы никогда не должны показывать пользователю реальные исключения. Вместо этого регистрируйте их в удобном для вас месте. Это может быть файл на сервере, в базе данных или даже в журналах событий Windows. Вам не обязательно писать собственный инструмент для ведения журнала, вы можете использовать все, что доступно в Интернете. Мне больше всего нравится SeriLog, поскольку я регистрирую большинство своих событий / исключений в текстовых файлах. Но я довольно долго использовал ELMAH с .NET Framework, и это было неплохо для журналов в формате XML. .

Это работает для меня, потому что:

  1. Пользователь проинформирован о проблеме и может связаться со службой поддержки.
  2. Я не предупреждаю злоумышленников о недостатках моей системы (по крайней мере, не ясно)
  3. Я знаю, какое исключение видел пользователь, благодаря предоставленному им коду ошибки
  4. Есть журналы, которые нужно анализировать, когда мне нужно
person Davidson Sousa    schedule 20.06.2019