Pull to refresh

Comments 12

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

ASP.NET Web API

Так ASP.NET или ASP.NET Core?


Не обрабатывайте TaskCanceledException как внутреннюю ошибку сервера, потому что таковой она не является: причина исключения в отмене запроса клиентом, так что наиболее подходящий HTTP-ответ — это 499.

Совершенно не обязательно причиной Task Canceled является отмена клиентом.


Я применяю наиболее доступный SHA-1, затем обрезаю результат до длины, достаточной для того, чтобы сохранить уникальность кода ошибки.

Эээ, а как вы гарантируете, что ваши 5 байт — уникальны?

Так ASP.NET или ASP.NET Core?

Имеется ввиду ASP.NET Core, так как meddlewares появились с ASP.NET Core, но так как официально Microsoft с выходом .NET 5 перестал добавлять в название технологий слово Core, а так же если вы откроете сайт ASP.NET, то вы не увидете упоминание слова Core, поэтому я также решил его не добавлять, не усложняя тем самым и без того длинное название ASP.NET Web Api.

Совершенно не обязательно причиной Task Canceled является отмена клиентом.

Да вы правы, но в обработчике обрабатывается именно случай отмены запроса пользователем, о чем говорит проверка свойста context.RequestAborted.IsCancellationRequested

Эээ, а как вы гарантируете, что ваши 5 байт — уникальны?

В примере длина кода 10 символов, соответственно это 10 байт, с достаточной вероятность код будет уникальный. exception.ToString() в базовой реализации возвращает текстовое представление включающее текст сообщения, тип исключения и stack trace. Я рекомендую не добавлять деталей связанных с конкретным запросом в текст сообщения, о чем написано в статье, соответственно если пользователи столкнутся с одной и той же проблемой то stack trace, тип ошибки и текст сообщения будут одинаковыми и хэш соответственно тоже. Но вы можете использовать для формирования кода ошибки любой другой предпочтительный для вас способ, я лишь предложил свою идею. Спасибо.

Да вы правы, но в обработчике обрабатывается именно случай отмены запроса пользователем, о чем говорит проверка свойста context.RequestAborted.IsCancellationRequested

… и не проверяется, что эксепшн — TaskCanceled. У вас код противоречит тексту.


В примере длина кода 10 символов, соответственно это 10 байт

Пять байт. Ваш же код:


hash[..5].Select(b => b.ToString("x"))

с достаточной вероятность код будет уникальный.

Достаточной — это какой? Сколько коллизий на тысячу ошибок?

… и не проверяется, что эксепшн — TaskCanceled. У вас код противоречит тексту.

Внес уточнение в текст.

Пять байт. Ваш же код:

Да код мой, извините действительно 5 байт, поторопился с ответом.

Достаточной — это какой? Сколько коллизий на тысячу ошибок?

Да они возможны, предложите, пожалуйста, методику тестирования на коллизии, буду признателен, спасибо

Да они возможны, предложите, пожалуйста, методику тестирования на коллизии, буду признателен, спасибо

Ну как, берете 100500 разных ошибок и смотрите, сколько разных кодов вы получите.


Но простая математика говорит нам, что даже при идеальном распределении (которого не будет) у вас не может быть больше, чем 256^5 ошибок. Это, казалось бы, много, но рекомендую помнить, что два разных стектрейса дадут разные ошибки, поэтому это пространство будет выбито раньше, чем вы думаете.

Имеется ввиду ASP.NET Core, так как meddlewares появились с ASP.NET Core, но так как официально Microsoft с выходом .NET 5 перестал добавлять в название технологий слово Core, а так же если вы откроете сайт ASP.NET, то вы не увидете упоминание слова Core, поэтому я также решил его не добавлять, не усложняя тем самым и без того длинное название ASP.NET Web Api.


Если не добавлять Core, то получается вы ссылаетесь на ASP.NET Web API другую технологию.

У вас ASP.NET Core.

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

Технология на которую вы ссылаетесь почти 3 года назад была полностью заменена ASP.NET Core

То-то я до сих пор работаю с этой "полностью замененной технологией", ага.


public void Configure(IApplicationBuilder app)
    {
        app.UseMiddleware<ErrorHandlerMiddleware>(); // Should be always in the first 
     ...

Может быть, лучше добавление такой инфраструктурной вещи сделать через IStartupFilter (подробности об этом механизме см., например, здесь)? Тогда ваш компонент ErrorHandlerMiddleware гарантированно будет добавлен в конвейер раньше всего, что добавляется через метод Configure Startup-класса, и не потребуется писать комментарий и надеяться, что его таки прочтут ;-).

Спасибо за совет, использование IStartupFilter выходит за рамки этой статьи. Целью кода о котором вы говорите было как можно более наглядно и просто показать регистрацию middleware в начале конвейера обработки запроса.

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

Вместо хеша я предпочитаю отдавать пользователю идентификатор корелляции (гуид), который

  • не нужно обфусцировать (он и так отдаётся на клиента в виде заголовка). Он не несёт какой-либо секретной информации для внешнего мира, поэтому минус медитация

  • максимально конкретен и, одновременно, распространяется по другим микросервисам. Поэтому когда пользователь с ним приходит, инженеру поддержки или разработчику достаточно вбить его в Кибану, чтобы получить картину от начала до конца

Sign up to leave a comment.

Articles