Когда я смотрю на метод в .NET Framework, он может вызвать несколько возможных исключений.

Что мне нужно спросить с точки зрения планирования для планирования и обработки этих исключений? Я понимаю, что в зависимости от воздействия исключения, это может повлиять на его отображение на уровне пользовательского интерфейса. Например, если серверный процесс, непрозрачный для взаимодействия с пользователем, выдает исключение, вы не захотите показывать это пользователю, поскольку он / она не будет знать, что это такое.

Благодарность

0
GurdeepS 4 Июл 2017 в 00:17
Управляемый компилятор VS помещает обработчик исключений по умолчанию в верхнюю часть стека выполнения, поэтому любое необработанное исключение в коде перехватывается обработчиком по умолчанию. Таким образом, размещение обработчика исключений в main перехватит все исключения, не перехваченные другими обработчиками в коде, и остановит обработчик по умолчанию от отображения сообщений о нежелательных исключениях.
 – 
jdweng
4 Июл 2017 в 00:25

2 ответа

Я хотел написать это как комментарий, но текстовое поле комментария слишком долго ...

  1. Есть исключения, которые важно показать пользователям, потому что они могут справиться с этим самостоятельно, например: имя файла недопустимо.

  2. Есть исключения, которые я считаю важным показать пользователям, потому что они (пользователи) будут работать как моя команда QA, например: какой-то метод не будет обновлять графический интерфейс, и они, вероятно, придут к выводу, что они должны сообщить об этом позже, они покажут мне исключение, и я обнаружу, что мой массив находится за пределами ...

  3. бывают исключения, когда продвижение их к пользователю просто сбивает их с толку и, как вы сказали,

"он / она понятия не имеет, что это такое"

Например, например:

«если непрозрачный процесс на бэкэнде выдает исключение».

Это исключение я сохраняю для себя (в базе данных ..) ..
Я всегда напоминаю себе, что у конечного пользователя другая психология по сравнению с разработчиком (-:

Надеюсь, я правильно понял ваш вопрос.

0
jonathana 4 Июл 2017 в 00:50

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

Вот пример пары классов, которые могут обрабатывать как неожиданные, так и настраиваемые исключения:

class Program
{
    static void Main(string[] args)
    {
        MethodInvokationResult result = SafeActionInvokator.HandleSafely(() =>
        {
            MyFakeBusinessEngine.DivideTwoNumbers(5, 0);
        });
        if (result.Exception is System.DivideByZeroException)
        {
            Debug.WriteLine($"A divide by zerp exception was caught");
        }
        else if (!result.Success)
        {
            Debug.WriteLine($"An unknown error occured.");
        }
    }
}

^ Вы видите, что вы можете обернуть вызовы и обработать их разумным способом.

public class MethodInvokationResult
{
    public bool Success { get; set; }
    public Exception Exception { get; set; }
}

^ Простой класс результатов

public static class MyFakeBusinessEngine
{
    /// <summary>
    /// Divides two numbers
    /// </summary>
    /// <param name="a">numerator</param>
    /// <param name="b">denominator</param>
    /// <returns>the result</returns>
    /// <exception cref="System.DivideByZeroException">When b is zero, divide by zero exception is thrown.</exception>
    public static int DivideTwoNumbers(int a, int b)
    {
        return a / b;
    }
}

^ Хорошо документированный метод, который даже сообщает другим разработчикам, какие исключения он ожидает выбросить.

public static class SafeActionInvokator
{
    /// <summary>
    /// Executes a method, and if any exception is thrown, will log the error and swallow the exception.
    /// </summary>
    /// <param name="methodToExecute"></param>
    public static MethodInvokationResult HandleSafely(Action methodToExecute)
    {
        try
        {
            methodToExecute.Invoke();
            return new MethodInvokationResult()
            {
                Exception = null,
                Success = true
            };
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"{ex}");
            return new MethodInvokationResult()
            {
                Exception = ex,
                Success = false
            };
        }
    }
}

^ Обертка для метода, который вы вызываете, заключая его в try catch, позволяет вам обрабатывать все исключения одинаковым образом или помещать туда любую настраиваемую логику, которую вы хотите.

Его можно расширить до вызова, который также может возвращать любое фактическое значение результата. Вы можете создать общий класс результатов вместо простого, которое я показал.

НАКОНЕЦ! Что касается вашего фактического вопроса, я бы создал некоторые из этих слоев во всем вашем приложении и повторно выбросил бы любые исключения с включенным рейтингом серьезности. Они будут распространяться на ваш слой пользовательского интерфейса, и вы можете выбирать, что делать, в зависимости от уровня серьезности.

Может даже что-то в этом роде!

public class MajorException : Exception { }
public class MediumException : Exception { }
public class MinorException : Exception { }
public class UserError : Exception { }

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

0
Dan Rayson 4 Июл 2017 в 00:52
Это довольно удобная техника, спасибо! Так, например, если в приложении есть критический файл, который удаляется (например, файл конфигурации), а затем приложение пытается его открыть, это будет серьезным (или фатальным) исключением. В таком случае я закрою приложение. Что я хочу сделать, так это создать блок-схему, которая будет изображать действия, которые я должен предпринять в исключительных случаях, в зависимости от их характера.
 – 
GurdeepS
4 Июл 2017 в 02:12
Блок-схема а? Я очень рекомендую yEd Graph Editor - совершенно бесплатно и потрясающе. Использую на работе! Пока вы можете определить, какие исключения вы ожидаете, вы сможете с ними справиться, потребуется некоторая сила человеческого мозга, чтобы распознать, что может пойти не так со строкой кода или блоком кода, например, с указанным вами доступом к файлу. Если вы можете это предвидеть, вы справитесь. Черт возьми, вы можете ожидать полного сбоя, пока исключение безопасно обрабатывается, ваше приложение может продолжать работу.
 – 
Dan Rayson
4 Июл 2017 в 02:20
Я должен добавить ... Возможно, вы захотите подумать, что делать, когда что-то выходит из строя, что может означать откат предыдущей операции. Это может показаться сложным, но есть шаблон UnitOfWork, который вы могли бы использовать, возможно, используя шаблон транзакции, предоставляемый платформой DotNet ... Я отвлекся.
 – 
Dan Rayson
4 Июл 2017 в 02:25
В моем случае приложение является ASP.NET и вращается вокруг создания учетных записей AD и управления ими. Большинство операций передаются в AD только при вызове метода Save (), поэтому нет возможности промежуточного состояния. Другой вопрос, который у меня есть - я вижу только две опции в обработке исключений - ведение журнала и сообщение пользователю - когда вы «обрабатываете» исключение, есть ли что-нибудь еще, что нужно сделать? И если вы откатываете операцию, будет ли это уловлено или, наконец, заблокировано?
 – 
GurdeepS
4 Июл 2017 в 02:51
Определенно стоит изучить шаблон единицы работы и встроенную систему транзакций, отличное место для начала: docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/…
 – 
Dan Rayson
4 Июл 2017 в 14:17