Aspnetcore: Глобальная обработка исключений

Созданный на 26 авг. 2019  ·  51Комментарии  ·  Источник: dotnet/aspnetcore

Привет, ребята, я хотел знать, как лучше всего перехватывать исключения на уровне приложения, чтобы не помещать try catch во все мои методы и компоненты и централизовать управление исключениями в одной точке (обычно показывать уведомление об ошибке и регистрировать исключение) .

так что есть лучший способ сделать это в preview8 или что-то запланированное для RTM?

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

Components Big Rock affected-most area-blazor enhancement severity-major

Самый полезный комментарий

Любое обновление по этому вопросу?

В настоящее время мое стороннее приложение blazor просто перестало отвечать на ввод пользователя после того, как возникло исключение.

Не рекомендуется покрывать все строки кода с помощью try-catch (и не ожидать, что разработчик сделает это), в случае «непредсказуемого» исключения у нас должен быть общий обработчик, который позволяет нам:

1. Выберите, следует ли разорвать цепь.
2. Покажите нашему пользователю «дружественное» сообщение с графическим интерфейсом или просто перенаправьте его на общую страницу ошибки.

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

Все 51 Комментарий

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

Хорошо, как я понимаю, я должен предоставить свою собственную реализацию ILogger? и в моей реализации мне приходится иметь дело с исключением? (например, показать уведомление, записать исключение в файл для серверной части и отправить его контроллеру для клиентской части)
на самом деле единственное, что можно найти, это этот пакет https://github.com/BlazorExtensions/Logging
Я не очень понимаю, как его использовать, кажется, мы можем войти в консоль только с этим.

Но даже с этим расширением, если в коде есть необработанное исключение, приложение вылетает.

так что, если я понимаю, у меня нет выбора, чтобы окружить весь мой код try catch ?

Спасибо за ваше объяснение

Любой из поставщиков регистраторов, перечисленных здесь: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#built -in-logging-providers, а также поставщики, разработанные сообществом ( https://github.com/aspnet/Extensions/tree/master/src/Logging#providers) должно работать.

Но даже с этим расширением, если в коде есть необработанное исключение, приложение вылетает.

Для Blazor на стороне сервера необработанное исключение должно отключить канал, но не привести к сбою приложения. Если блок предназначен для создания исключения, которое вы можете допустить, try-catch кажется наиболее разумным способом продолжить. Что вы планируете делать с необработанными исключениями, если вы поймаете произвольное исключение?

Blazor на стороне клиента не регистрирует никаких исключений. Они просто выводятся на консоль. Вот код из WebAssemblyRenderer

protected override void HandleException(Exception exception)
{
    Console.Error.WriteLine($"Unhandled exception rendering component:");
    if (exception is AggregateException aggregateException)
    {
        foreach (var innerException in aggregateException.Flatten().InnerExceptions)
        {
            Console.Error.WriteLine(innerException);
        }
    }
    else
    {
        Console.Error.WriteLine(exception);
    }
}

Единственный способ, которым я нашел, что может перехватывать исключения, описан здесь
https://remibou.github.io/Exception-handling-in-Blazor/

Но я бы не назвал это обработкой исключений...

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

{
   IsLoading = true;
   await SomeAsync();
}
finally
{
   IsLoading = false;
   //force rerender after exception
    StateHasChanged();
}

Если метод SomeAsync выдает исключение, для моей переменной IsLoading устанавливается значение false, но мое представление не перерисовывается. Вы должны вызвать SetStateHasChanged в блоке finally, чтобы принудительно выполнить повторную визуализацию.

для blazor на стороне клиента я, наконец, пишу свою собственную реализацию на ILogger (вдохновленный кодом реализации по умолчанию, который регистрируется в консоли).
С этой реализацией я могу вызвать LoggerController на своем сервере, который также вводит ILogger (но на этот раз его реализация NLog вводится, поэтому я могу правильно записать все исключения на сервере)

Я отказываюсь от идеи глобальной обработки исключений, которая, похоже, не соответствует логике blazor, и везде ставлю try/catch и внедряю ILogger.во всех компонентах.

Кроме того, если вы считаете, что есть лучше сделать, вы можете закрыть этот вопрос.

Я думаю, что это отсутствующая функция. Когда возникает исключение, я также хотел бы иметь централизованное место для захвата всех необработанных исключений и что-то делать.. Либо отображать его во всплывающем окне, регистрировать его где-то, отправлять на сервер или что-то еще .. без какого-либо вреда для состояния приложения
Что-то вроде события UnhandledException в WPF
https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netframework-4.8

Разве ILogger уже не является централизованным местом?

@SteveSandersonMS посмотрите на мой комментарий выше
https://github.com/aspnet/AspNetCore/issues/13452#issuecomment-535227410
Исключения (в блазоре на стороне клиента) записываются на консоль с помощью Console.Error.WriteLine, они не регистрируются с помощью ILogger. Вы можете реализовать собственный TextWriter и заменить Console.Error
https://remibou.github.io/Exception-handling-in-Blazor/
но вы получаете строковое представление исключения. Анализ этой строки, которая включает трассировку стека, и попытка получить (например) только сообщение об исключении, по крайней мере, громоздки.
Я хотел бы получить доступ к объекту исключения, чтобы я мог вести собственное ведение журнала (или что-то еще)

@rborosak Спасибо за разъяснение!

Любое обновление по этому вопросу?

В настоящее время мое стороннее приложение blazor просто перестало отвечать на ввод пользователя после того, как возникло исключение.

Не рекомендуется покрывать все строки кода с помощью try-catch (и не ожидать, что разработчик сделает это), в случае «непредсказуемого» исключения у нас должен быть общий обработчик, который позволяет нам:

1. Выберите, следует ли разорвать цепь.
2. Покажите нашему пользователю «дружественное» сообщение с графическим интерфейсом или просто перенаправьте его на общую страницу ошибки.

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

@hagaygo Очень хорошее резюме!

@SteveSandersonMS Пожалуйста, учтите это для вехи 3.1.x! Пожалуйста, не переносите это на 5.0.0

Привет,

Я получаю такую ​​​​ошибку, когда цепь разрывается в консоли окна разработчика.

image

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

@SteveSandersonMS Не могли бы вы уточнить, работает ли app.UseExceptionHandler() для блазора на стороне сервера?

Я видел несколько случаев, когда мой пользовательский ErrorHandler не перехватывал исключения, выдаваемые моим приложением. Пример кода

Startup.cs :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
    ...
    app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ErrorHandler.HandleError });
    ...
}

ErrorHandler.cs :

public static async Task HandleError(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>()?.Error;
    var message = error?.Message ?? "[EXCEPTION NOT FOUND]";        
    return;
}

Например, когда мой репозиторий выдает исключение как таковое:
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

Мое решение MVC перехватывает все исключения и использует аналогичные реализации ErrorHandling.

Переносим это в выпуск 5.0 , чтобы выделить здесь конкретные вопросы и посмотреть, сможем ли мы решить некоторые из них.

самая большая проблема для меня - границы ошибок . я хочу иметь возможность использовать сторонний компонент и каким-то образом обернуть использование этого компонента обработкой ошибок, чтобы ошибка в библиотеке не убивала все мое веб-приложение. прямо сейчас нет «куда поставить try catch» — все дерево компонентов контролируется blazor renderer, который умрет, если что-то в глубине дерева испортится.

+1 за эту функцию.
Необходимость помещать блок try/catch во все методы не является разумным способом.

Я лично использовал исключение для управления бизнес-ошибками. На высоком уровне я перехватываю исключение и в зависимости от его типа решаю, нужно ли регистрировать исключение, отображать его для пользователя и отображать ли полное сообщение (исключения для бизнеса) или просто "Что-то идет не так") .

На самом деле, единственный способ сделать что-то подобное, который я нашел, - это создать класс ComponentBaseEx, который наследуется от ComponentBase и переопределяет OnInitialized (Async), OnParametersSet (Async),...
К сожалению, даже при таком пути мне приходится вручную управлять всеми действиями пользователя (удалить клиента, ...)

Ты думаешь
1) что-то можно сделать?
2) если да, то когда?

Вот мой сценарий: настольное/гибридное приложение Blazor с использованием сервера Blazor. Один пользователь вошел в систему за раз, и состояние сохраняется при перезагрузке. Таким образом, если есть необработанное исключение, нет другого способа вернуть приложение в заслуживающее доверия состояние, кроме его перезапуска. Нам нужно поймать необработанные исключения, показать соответствующий UX, а затем завершить работу. Стандартный шаблон настольного приложения.

Временный взлом: мы настроили ведение журнала с помощью Serilog. Serilog имеет API, который позволяет фильтровать все сообщения журнала и решать, будут ли они отправлены. Мы злоупотребляем этим API, проверяя, имеет ли событие журнала ключ CircuitId в своем словаре свойств. Если это так, это означает, что цепь умерла, т. е. есть необработанное исключение. Мы можем получить оскорбительное исключение из объекта сообщения журнала, который мы исследовали. Presto — вы держите в руках необработанное исключение в самом верху и можете делать с ним все, что хотите.

Привет, ребята, как и другие, я очень беспокоюсь, если вы перенесете это на веху .NET 5.
После года работы над blazor, переписав старое приложение Silverlight, я собираюсь развернуть свое приложение в производстве в мае/июне (когда webassemble будет готов к производству).

Но я определенно не могу этого сделать без сильного способа поймать или, по крайней мере, зарегистрировать все неожиданные ошибки.

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

Вам большое спасибо!

Привет, я в той же ситуации, что и @julienGrd
Пожалуйста, сделайте что-нибудь, чтобы помочь/направить нас.
С Уважением!

То же самое и со мной.

Мы использовали серверную часть Blazor для всей нашей разработки и мигрировали с
устаревшие веб-страницы ASP.Net.

Во вторник, 3 марта 2020 г., в 12:02 [email protected]
написал:

Привет, я в той же ситуации, что и @julienGrd
https://github.com/julienGrd
Пожалуйста, сделайте что-нибудь, чтобы помочь/направить нас.
С Уважением!


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/dotnet/aspnetcore/issues/13452?email_source=notifications&email_token=ANKYSDFSUQ3OTBGWQMRV5EDRFUZ27A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENUJXL51-590comment,5940comment,5940comment
или отписаться
https://github.com/notifications/unsubscribe-auth/ANKYSDGFCDRMZV2N4NLMOMLRFUZ27ANCNFSM4IPQWA6Q
.

--
Анкит Бансал

*Научные игры*

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

Однако есть еще часть этого, которую мы еще не реализовали. Это отслеживается https://github.com/dotnet/aspnetcore/issues/19533. Мы обязательно сделаем это в ближайшее время.

вы должны иметь возможность регистрировать все неперехваченные исключения с помощью интерфейса ILogger.

@SteveSandersonMS Я думаю, что нам нужен гораздо более общий API, который просто передает вам неперехваченное исключение, чтобы делать все, что мы хотим, _с самим исключением._ Представьте, что мы хотим изучить исключение и, возможно, как-то отреагировать, возможно, отправить исключение для службы отслеживания исключений, такой как Raygun, или представить некоторый пользовательский интерфейс на основе содержимого. Без такого API нам нужно неправильно использовать интерфейс ILogger для выполнения всех этих задач, что неудобно. Почему бы просто не предоставить гораздо более общий API вместо того, чтобы навязывать все возможные сценарии через реализацию ILogger?

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

@SteveSandersonMS У вас случайно нет эталонного примера, чтобы сделать это в приложении Blazor на стороне сервера? Мое намерение состоит в том, чтобы после регистрации неперехваченного исключения показать пользователю дружественное сообщение. Помощь будет оценена. С Уважением.

@eliudgerardo Blazor Server уже отображает некоторый пользовательский интерфейс, когда возникает необработанная ошибка. Вы можете настроить этот пользовательский интерфейс. Документы об этом находятся по адресу https://docs.microsoft.com/en-us/aspnet/core/blazor/handle-errors?view=aspnetcore-3.1#detailed-errors-during-development .

@SteveSandersonMS Я знаю об этой опции, которую вы упомянули, но я боюсь, что в этом случае цепь соединения будет разорвана, и я не хочу оборачивать все свои вызовы API с помощью try/catch. Так есть ли способ сделать это?

@eliudgerardo Почему так важно, что цепь разорвана? Ваша цель каким-то образом позволить пользователю продолжать использовать схему даже после необработанного исключения?

@SteveSandersonMS Мы не хотим, чтобы цепь разорвалась! Если возникает исключение (в нашем приложении или где-то в сторонней библиотеке, которую мы используем), нам нужно место, где мы могли бы отображать диалоговое окно с сообщением «Что-то пошло не так {exception.Message}», и приложение продолжало бы работать. У нас есть частичное решение этой проблемы, заключаем методы жизненного цикла и наши методы в блок try catch, но это громоздко, и есть проблема со сторонними библиотеками...

@partyelite Если исключение не обработано, то эта цепь теперь находится в неизвестном состоянии. Мы больше не можем сказать, можно ли еще использовать какие-либо ресурсы внутри него, была ли полностью выполнена ваша логика безопасности или что-то еще. Если цепь будет продолжать использоваться, это может привести к неопределенному поведению, включая потенциальные проблемы с безопасностью, что проблематично, учитывая, что этот код работает на вашем сервере.

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

Как вы думаете, такой подход удовлетворит ваши потребности?

Мне определенно нравится идея иметь встроенную границу компонента для ошибок.

Это было бы превосходно. Но я думаю, что нам все еще нужен метод (у которого есть исключение, которое возникло в качестве входного параметра), который мы могли бы переопределить и сделать что-то с этим исключением, например, отобразить диалоговое окно с подробностями об исключении или отправить сведения об исключении на сервер, где они будут зарегистрированы. БД что ли..
Я знаю, что что-то подобное сейчас можно сделать с помощью ILogger, но мы получаем строку в качестве входного параметра, и получить какие-то конкретные данные из исключения в строковом формате очень сложно.

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

<MyApp>
    <HandleErrors>
        <ThirdPartyComponent />
    </HandleErrors>
    <HandleErrors>
        <SomeOtherComponent />
    </HandleErrors>
</MyApp>

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

в чем-то вроде WPF использование строгого разделения представления/модели смягчает эту проблему; лучше всего использовать MVVM или MVC или что-то еще и иметь обработку ошибок вокруг логики, которая запускается или обновляет представление. однако грубые идиоматические взгляды слишком императивны и подвержены ошибкам, чтобы это было разумно. трудно написать файл .xaml, который остановит приложение, но в .razor тривиально иметь необработанное исключение во время рендеринга , будь то из-за привязки данных к свойству, поддерживаемому ORM, или просто потому, что вы написали

<strong i="7">@if</strong> (mightBeNull.Value) {
    <br>
}

Разве ILogger уже не является централизованным местом?

Как и @julienGrd, мне нужен способ глобального перехвата MsalUiRequiredException , чтобы я мог перенаправить пользователя на вход для запроса дополнительных областей. В MVC есть фильтр исключений действий, который обрабатывает это, но Blazor не имеет эквивалента.

Может быть, ILogger — это то место, где я должен как-то это сделать? Если это так, то это плохо. Мое исключение связано с аутентификацией, поэтому это сквозная проблема, и мне нужен способ справиться с ней, который не загрязняет все мое приложение.

@kenchilada Я знаю, кажется, что добавление «глобального» обработчика исключений было бы быстрым решением вашей проблемы, но каждый раз, когда вы используете этот подход, ваш код полностью теряет отслеживание выполняемого потока. У вас нет способа сохранить состояние и нет способа предоставить UX, который не просто отбрасывает все, что происходило в то время. В общем, гораздо лучше поместить конкретную попытку/перехват в пользовательский интерфейс, который может вызвать его, чтобы вы могли продолжить, не отбрасывая все локальное состояние.

Однако, если вы действительно хотите справиться с этим на «глобальном» уровне, тогда да, ILogger — это способ, которым вы можете это сделать.

Проблема в том, что обработка на основе try-catch невозможна с моделью RenderTreeBuilder. Ты можешь написать

<strong i="6">@try</strong>
{
    <p>@{throw new Exception();}</p>
}
catch (Exception e)
{
    <p>An error occurred.</p>
}

.. но он не будет отображать «Произошла ошибка», он разрушит всю схему. Вы даже не получаете журнал консоли и #blazor-error-ui.

@SteveSandersonMS Я полностью согласен с вами в «теории», но я в конкретном контексте, где я не знаю, как с этим справиться, может быть, у вас будут некоторые ответы.

Я синхронизирую много кода из существующего приложения Silverlight, которое я выполняю техническим переходом на blazor, но сохраняю совместимость и совместно использую код между двумя приложениями, потому что объем работы огромен, и два приложения должны работать бок о бок в течение некоторого времени. .

поэтому моя проблема заключается в том, что ViewModel синхронизируется на стороне клиента, вызывая службы wcf следующим образом:
````
общественная недействительная MyFunction () {
wcfClient.MyFunctionCompleted += MyFunctionCompleted;
wcfClient.MyFunction();
}

private void MyFunctionCompleted (отправитель объекта, аргументы MyFunctionCompletedArgs) {
//результат здесь, а также потенциальное исключение
//мы должны считать этот код небезопасным, поэтому есть способ его перехватить
}
````

поэтому, когда я вызываю метод моей модели представления в своем представлении blazor, бесполезно делать что-то подобное
private void ButtonClick(){ try{ myViewModel.MyFunction(); } catch(Exception ex){ //i can't catch the exception in the service or happened in the callback } }

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

Спасибо за вашу помощь !

в этом случае вы могли бы использовать TaskCompletionSource. скажем, MyFunctionCompletedArgs содержит либо исключение, либо значение типа TResult, это будет примерно так:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

затем на стороне Blazor дождитесь завершения обещания:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Существует множество сценариев программирования/программного обеспечения.

Мой вывод из этого обсуждения заключается в том, что Microsoft (по крайней мере, в настоящее время) не хочет, чтобы мы использовали Blazor для «больших» приложений или бизнес-приложений, поскольку они ожидают, что мы везде будем размещать блоки try/catch.

Таким образом, вы можете создавать «маленькие» приложения. (также, как я уже упоминал, это не очень хорошая практика)

Но LOB-приложения с множеством вариантов использования и 10-20 (а то и больше) разработчиков в команде так работать не могут.

Конечно, на данный момент есть еще проблемы с Blazor, но эта проблема возникла примерно через 10-15 минут после начала сборки POC.

Привет,

Правильно сказано. Надеюсь, Microsoft предоставит обновление для этой части в конце этого года.

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

В Blazor есть много вещей, которые нуждаются в полировке.

С уважением,

Анкит Бансал

Научные игры

От: Hagay [email protected]
Отправлено: вторник, 26 мая 2020 г., 00:21
Кому: dotnet/aspnetcore [email protected]
Копия: bansalankit2601, [email protected] ; Комментарий [email protected]
Тема: Re: [dotnet/aspnetcore] [Blazor] Глобальная обработка исключений (#13452)

Существует множество сценариев программирования/программного обеспечения.

Мой вывод из этого обсуждения заключается в том, что Microsoft (по крайней мере, в настоящее время) не хочет, чтобы мы использовали Blazor для «больших» приложений или бизнес-приложений, поскольку они ожидают, что мы везде будем размещать блоки try/catch.

Таким образом, вы можете создавать «маленькие» приложения. (также, как я уже упоминал, это не очень хорошая практика)

Но LOB-приложения с множеством вариантов использования и 10-20 (а то и больше) разработчиков в команде так работать не могут.

Конечно, на данный момент есть еще проблемы с Blazor, но эта проблема возникла примерно через 10-15 минут после начала сборки POC.


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-633799650 или отмените подписку https://github.com/notifications/unsubscribe-auth/ANKYSDATEUMBPN43PYQU2ZDRTM7T3ANCNFSM4IPQWA6Q . https://github.com/notifications/beacon/ANKYSDD3JBBDUMUWMZ5NQXDRTM7T3A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEXDQHYQ.gif

Существует множество сценариев программирования/программного обеспечения.

Мой вывод из этого обсуждения заключается в том, что Microsoft (по крайней мере, в настоящее время) не хочет, чтобы мы использовали Blazor для «больших» приложений или бизнес-приложений, поскольку они ожидают, что мы везде будем размещать блоки try/catch.

Таким образом, вы можете создавать «маленькие» приложения. (также, как я уже упоминал, это не очень хорошая практика)

Но LOB-приложения с множеством вариантов использования и 10-20 (а то и больше) разработчиков в команде так работать не могут.

Конечно, на данный момент есть еще проблемы с Blazor, но эта проблема возникла примерно через 10-15 минут после начала сборки POC.

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

@gulbanana спасибо за совет! Не уверен, что смогу сохранить совместимость с приложением silverlight с таким кодом, но я должен попробовать (даже если я предпочитаю решение для глобальной обработки исключений)

в этом случае вы могли бы использовать TaskCompletionSource. скажем, MyFunctionCompletedArgs содержит либо исключение, либо значение типа TResult, это будет примерно так:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

затем на стороне Blazor дождитесь завершения обещания:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Немного запутался здесь... Если глобальная обработка исключений невозможна, то почему существует продукт?
для blazor, который утверждает, что «Все неперехваченные исключения автоматически регистрируются»?:
https://docs.elmah.io/logging-to-elmah-io-from-blazor/

@ rono1 Теперь вы можете подключиться к конвейеру ведения журнала и регистрировать исключения - это не означает, что вы «обработали» исключение, просто вы можете глобально регистрировать их. Я благодарен за регистрацию, хотя!

Мы перенесли эту проблему в этап Backlog. Это означает, что он не будет работать над предстоящим релизом. Мы проведем повторную оценку невыполненной работы после текущего выпуска и рассмотрим этот пункт в то время. Чтобы узнать больше о нашем процессе управления проблемами и получить больше информации о различных типах проблем, вы можете прочитать наш процесс сортировки .

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

Как вы думаете, такой подход удовлетворит ваши потребности?

@SteveSandersonMS Рассматривается ли это для реализации? Это приведет к лучшему пользовательскому опыту и более надежному программному обеспечению.

+1 по этому поводу. Мы действительно должны оборачивать каждое событие в try/catch ? Я только что спустился в кроличью нору, пытаясь обойти это с помощью некоторых базовых компонентов для управления состоянием из-за того, насколько это болезненно.

+1 также на этом. Подход try/catch действительно не подходит для более крупных решений с несколькими разработчиками.

Я обратился к этому в своем приложении blazor на стороне клиента с помощью специального поставщика ведения журнала:
https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Кажется немного странным использовать логгер в качестве глобального обработчика исключений, но на данный момент я не нашел более чистого подхода 😞

Команде Blazor определенно нужно что-то с этим делать.
запрос/вопрос.

Вс, 4 октября 2020 г., 15:24, Маркус Рейнхардт, [email protected]
написал:

>
>
>

Я обратился к этому в своем приложении blazor на стороне клиента, используя пользовательское ведение журнала.
провайдер:

https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Кажется немного странным использовать регистратор в качестве глобального обработчика исключений, но я
на данный момент не нашел более чистого подхода 😞


Вы получаете это, потому что подписаны на эту тему.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-703255415 ,
или отписаться
https://github.com/notifications/unsubscribe-auth/AEVARXEEHAOU532C26QCGXLSJBZRRANCNFSM4IPQWA6Q
.

Спасибо что связались с нами.
Мы переносим эту проблему на этап Next sprint planning для будущей оценки/рассмотрения. Мы оценим запрос, когда будем планировать работу для следующего этапа. Чтобы узнать больше о том, чего ожидать дальше и как будет решаться эта проблема, вы можете прочитать подробнее о нашем процессе сортировки здесь .

Для тех, кто ищет обходной путь на стороне клиента:

function reportError(error) {
  if (DotNet) {
    DotNet.invokeMethodAsync('MyApp.Client', 'NotifyError', error);
  }
}

var exLog = console.error;
console.error = function (msg) {
  exLog.apply(console, arguments);
  reportError(msg);
}

window.addEventListener("unhandledrejection", function (promiseRejectionEvent) {
  reportError(promiseRejectionEvent.reason.message);
});
  public partial class AppLayout
  {
    [JSInvokable("NotifyError")]
    public static void NotifyError(string error)
    {
      //Handle errors
    }
  }

Поддержка браузера

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

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги