Re[4]: обработка ошибок
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.04.22 12:20
Оценка: +3
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, gandjustas, Вы писали:



G>>Стоит ли в данном случае изнутри БЛ кидать ArgumentException? Нужно ли в таком случае выдавать 400 клиенту? Или это уже 500 ошибка?


vaa>Это общая проблема, если ловим конкретное исключение, то можно 400, если другое 500.

Про 400 и 500 это был провокационный вопрос.
Ответ в стандарте — если клиент получает 400, то он не должен пытаться повторить запрос с теми же параметрами.
Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.
Re[2]: обработка ошибок
От: MadHuman Россия  
Дата: 08.04.22 12:37
Оценка: 9 (1)
Здравствуйте, vaa, Вы писали:


vaa>еще можно без спец искл.

vaa>
vaa>(bool, string) ValidateArgOne(string arg)
vaa>{
vaa>    .....
vaa>    return (false, "Ошибка");
vaa>}
vaa>

точно! по моему лучший вариант. вместо исключения возвращать Result, аля ФП F# подход с Result<'ok, 'err> , я ведь даже его знал.. но не сразу вспомнил
и волки сыты и овцы целы!

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

type ErrorKind = InvalidArg of string * string
type Result = Ok | Error of ErrorKind

let getThing arg1 = 
  //bla bla
  if not (some condition) then 
    Error("arg1", "arg1 invalid")
  else
    //do ok work
    Ok
Отредактировано 08.04.2022 13:19 MadHuman . Предыдущая версия .
Re[3]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 08.04.22 12:43
Оценка: +1
Здравствуйте, MadHuman, Вы писали:

MH>и волки сыты и овцы целы!


Ага, только куча логики по прокидыванию этого резалта через весь коллстек, и возвращаемые типы все в стиле maybe монады.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: обработка ошибок
От: MadHuman Россия  
Дата: 08.04.22 13:15
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, MadHuman, Вы писали:


MH>>и волки сыты и овцы целы!


НС>Ага, только куча логики по прокидыванию этого резалта через весь коллстек

в исходном примере, речь про один уровень.

НС>, и возвращаемые типы все в стиле maybe монады.

да, невижу в этом неудобств или недостатков.
ну и если быть точным не maybe (она про Some | None), а про Result ( Ok | Error ), где Error может включать доп информацию, а None из maybe нет
Re[5]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 08.04.22 15:00
Оценка:
Здравствуйте, MadHuman, Вы писали:

НС>>Ага, только куча логики по прокидыванию этого резалта через весь коллстек

MH>в исходном примере, речь про один уровень.

Исключения как раз придумали чтобы уйти от лапши, которую порождают коды возврата. А тут какой то back to the future.

НС>>, и возвращаемые типы все в стиле maybe монады.

MH>да, невижу в этом неудобств или недостатков.

Это в шарпе то?

MH>ну и если быть точным не maybe (она про Some | None), а про Result ( Ok | Error ), где Error может включать доп информацию, а None из maybe нет


Не принципиально.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: обработка ошибок
От: MadHuman Россия  
Дата: 08.04.22 15:49
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, gandjustas, Вы писали:


G>>Что мешает просто в отдельный метод вынести? Или даже в отдельный класс?


НС>К примеру, для проверки могут потребоваться промежуточные данные, которые затем используются для собственно вычислений.

сразу виден обширный практический опыт) согласен с аргументацией
Re[6]: обработка ошибок
От: IncremenTop  
Дата: 08.04.22 18:39
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Исключения как раз придумали чтобы уйти от лапши, которую порождают коды возврата. А тут какой то back to the future.


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


НС>Это в шарпе то?


Есть либы для этого. Гораздо удобнее и нагляднее, в отличие от стандартных исключений.
Re[7]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 08.04.22 18:53
Оценка:
Здравствуйте, IncremenTop, Вы писали:

НС>>Исключения как раз придумали чтобы уйти от лапши, которую порождают коды возврата. А тут какой то back to the future.

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

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

IT> Если приложение слоистое, то лучше использовать алгебраические типы.


В шарпе нет алгебраических типов.

НС>>Это в шарпе то?

IT>Есть либы для этого. Гораздо удобнее и нагляднее, в отличие от стандартных исключений.

Здесь должен быть пример.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[8]: обработка ошибок
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 09.04.22 06:34
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здесь должен быть пример.


Result result = new Result.Ok("OK");

WriteLine(result switch
{
    Result.Ok x => "200 " + x.Result,
    Result.Error e => "400 " + e.Err
});

public record Result()
{
    public record Ok(string Result) : Result();
    public record Error(string Err) : Result();
}
Re[9]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 09.04.22 07:48
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>
vaa>Result result = new Result.Ok("OK");

vaa>WriteLine(result switch
vaa>{
vaa>    Result.Ok x => "200 " + x.Result,
vaa>    Result.Error e => "400 " + e.Err
vaa>});

vaa>public record Result()
vaa>{
vaa>    public record Ok(string Result) : Result();
vaa>    public record Error(string Err) : Result();
vaa>}
vaa>


ЧТД. Ровно 100% этого кода при использовании исключений можно выкинуть.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: обработка ошибок
От: MadHuman Россия  
Дата: 09.04.22 08:57
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

vaa>>
vaa>>Result result = new Result.Ok("OK");

vaa>>WriteLine(result switch
vaa>>{
vaa>>    Result.Ok x => "200 " + x.Result,
vaa>>    Result.Error e => "400 " + e.Err
vaa>>});

vaa>>public record Result()
vaa>>{
vaa>>    public record Ok(string Result) : Result();
vaa>>    public record Error(string Err) : Result();
vaa>>}
vaa>>


НС>ЧТД. Ровно 100% этого кода при использовании исключений можно выкинуть.


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

паттерн Result лучше, когда ошибочная ситуация ожидаема и часть штатного поведения, в этом случае лучше и перф (иногда это важно).
и мы точно знаем все ожидаемые исходы из самого типа результата.
решается и исходная проблема топика — неоднозначность места исключения (возникло ли оно внутри самой функции и то что мы и хотим словить либо из более глубоких недр).
ввод нового класса исключения по бойлерплейту будет примерно тоже что ввод нового класса Result для конкретного случая.
Re[11]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 09.04.22 09:03
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>вместо свитча — будет try/catch. я бы сказал примерно одно и тоже.


Не будет там никакого try..catch, в этом суть. Просто вешается единожды написанная простенькая мидлвера. А вот твой Result придется явно протаскивать по всему коллстеку, загаживая код.
Еще раз — единственная фича исключений, ради которой их придумали — возможность абсолютно независимо от любого коллстека прервать выполнение и вернуть ошибку. И все это происходит абсолютно прозрачно для любого кода между источником и конечным обработчиком. А вот вариант с возвращаемыми кодами ошибок откатывает нас во времена до исключений, когда любой код приходилось специально под обработку ошибок затачивать. Особенно эротично это было в случае наличия колбеков. Вот есть некий библиотечный код, не твой. Ему на вход идет твой собственный колбек, в котором, внезапно, возникает ошибка. В случае с исключениями все работает, а вот что делать с кодами ошибок?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: обработка ошибок
От: Буравчик Россия  
Дата: 09.04.22 09:12
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.


Все равно это должна быть какая-то ошибка 4xx, а не 5xx
Best regards, Буравчик
Re[12]: обработка ошибок
От: MadHuman Россия  
Дата: 09.04.22 09:22
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:


MH>>вместо свитча — будет try/catch. я бы сказал примерно одно и тоже.

НС>Не будет там никакого try..catch, в этом суть. Просто вешается единожды написанная простенькая мидлвера. А вот твой Result придется явно протаскивать по всему коллстеку, загаживая код.
тогда мы вернёмся к исходной проблеме. вот мидлвара словила исключение (даже наше спец исключение типа WrongAccountException), если под мидлварей вызов функции вида Transfer (из которой напрямую это исключение и возвращается),
то да — всё хорошо, возвращаем 400, т.к. номер счета передан снаружи неверно. но исключение может подняться по колстэку и из глубин бизнес-логики, и на вызывающей стороне (хандлере под мидлаварей) и не было речи ни о каком счете.
а когда у нас в частном случае появится новое исключение — снова идти править общую мидлвару?


НС>Еще раз — единственная фича исключений, ради которой их придумали — возможность абсолютно независимо от любого коллстека прервать выполнение и вернуть ошибку. И все это происходит абсолютно прозрачно для любого кода между источником и конечным обработчиком.

да, всё так.

НС>А вот вариант с возвращаемыми кодами ошибок откатывает нас во времена до исключений, когда любой код приходилось специально под обработку ошибок затачивать.

этот вариант надо использовать когда в конкретном случае он имеет преимущества перед кэтчем исключения. если его всегда использовать/злоупотреблять, то конечно мы получим как в Go и всё то о чем ты говориш (не надо так).
Отредактировано 09.04.2022 9:23 MadHuman . Предыдущая версия .
Re[13]: обработка ошибок
От: Ночной Смотрящий Россия  
Дата: 09.04.22 09:31
Оценка:
Здравствуйте, MadHuman, Вы писали:

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


Вот поэтому и вводится специальный класс бизнес-исключений.

НС>>А вот вариант с возвращаемыми кодами ошибок откатывает нас во времена до исключений, когда любой код приходилось специально под обработку ошибок затачивать.

MH>этот вариант надо использовать когда в конкретном случае он имеет преимущества перед кэтчем исключения.

И что это за преимущества?

MH> если его всегда использовать/злоупотреблять, то конечно мы получим как в Go


В Go ситуация существенно лучше, потому что там весь код под такое заточен. А в дотнете это полный ахтунг.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: обработка ошибок
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.04.22 18:59
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, gandjustas, Вы писали:


G>>Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.


Б>Все равно это должна быть какая-то ошибка 4xx, а не 5xx


Почему? И какая?
Re[7]: обработка ошибок
От: Буравчик Россия  
Дата: 09.04.22 21:32
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Почему? И какая?


400 (если используются generic-коды ответов) или 422 (если ближе к HTTP).
Потому что от клиента неправильный запрос — который невозможно выполнить
Best regards, Буравчик
Re[5]: обработка ошибок
От: yenik  
Дата: 11.04.22 13:51
Оценка:
G>Ответ в стандарте — если клиент получает 400, то он не должен пытаться повторить запрос с теми же параметрами.
G>Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.

В стандарте одно, а в жизни другое. Например: https://github.com/IdentityServer/IdentityServer4/blob/5bcc2abbcf6c47200c4eb3b77e756f1bc0e04358/src/IdentityServer4/src/Endpoints/Results/TokenErrorResult.cs#L29
И не только тут такое практикуется.
Re[6]: обработка ошибок
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.04.22 14:28
Оценка:
Здравствуйте, yenik, Вы писали:

G>>Ответ в стандарте — если клиент получает 400, то он не должен пытаться повторить запрос с теми же параметрами.

G>>Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.

Y>В стандарте одно, а в жизни другое. Например: https://github.com/IdentityServer/IdentityServer4/blob/5bcc2abbcf6c47200c4eb3b77e756f1bc0e04358/src/IdentityServer4/src/Endpoints/Results/TokenErrorResult.cs#L29

Y>И не только тут такое практикуется.

Где тут возврат 400 для рантайм эксепшена?
Re[7]: обработка ошибок
От: yenik  
Дата: 11.04.22 14:32
Оценка:
G>>>Ответ в стандарте — если клиент получает 400, то он не должен пытаться повторить запрос с теми же параметрами.
G>>>Это означает, что 400 нельзя кидать для ситуаций, которые могут меняться со временем и для любых rntime эксепшенов.

Y>>В стандарте одно, а в жизни другое. Например: https://github.com/IdentityServer/IdentityServer4/blob/5bcc2abbcf6c47200c4eb3b77e756f1bc0e04358/src/IdentityServer4/src/Endpoints/Results/TokenErrorResult.cs#L29

Y>>И не только тут такое практикуется.

G>Где тут возврат 400 для рантайм эксепшена?


Здесь возврат 400 для запроса, некорректного с точки зрения бизнес-логики. Запрос, который некорректен сегодня, может стать корректным завтра. И тогда его можно смело повторить и он вернёт 200.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.