170 похожих чатов

Пишу rest api на asp.net core. Стараюсь поддерживать контроллеры насколько

можно чистыми. Есть action, который принимает id и возвращает документ. Единственное что делает контроллер, это вызывает EntityService.GenerateDoc(id); Но что делать, если такого id не существует? Пока рассматривал следующие варианты:
1) Возвращать null. Это дает абсолютно ноль информации вызывающему методу о том, что действительно произошло(id нет или проблема возникла с генерацией документа).
2) Кидать exception. Решает проблему первого варианта, но логически не стыкуется. Ситуация не критичная(not exceptional), зачем тогда exception кидать. Еще возможно perf будет страдать.
3) Поменять сигнатуру сервиса и принимать сам объект, а не id. Контроллер берет на себя слишком много ответственности. Возможно со временем разрастется еще больше.
4) Возвращать из сервиса result объект. С таким никогда не работал, так что не знаю, надо ли с этим заморачиваться. Ведь тогда предпочтительнее везде result использовать.
Какие еще есть варианты обработки не критических ошибок в приложении? Если выбирать из описанных выше вариантов, то что предпочтительнее?

36 ответов

16 просмотров

Если в нормальной работе сервиса не ожидаются несуществующие ID, то не вижу ничего дурного кидать исключение.

Во флудильне на днях обсуждали Как вариант, возвращать 422.

Кидай просто BadRequest

SightRo- Автор вопроса
Andrew Shurunov
Во флудильне на днях обсуждали Как вариант, возвра...

Это понятно, что контроллер должен вернуть http код. Я понять не могу, что сам сервис должен возвращать в таком случае.

SightRo
Это понятно, что контроллер должен вернуть http ко...

А Если несколько вариантов, почему не удалось так сделать, то я бы кидал исключение

SightRo- Автор вопроса
SomebodyOdd
Если в нормальной работе сервиса не ожидаются несу...

Я вот на этот вопрос и ищу ответ. То есть сервис обращаясь к бд проверяет есть ли такая запись. Если ее нет, та какие действия предпочтительнее принять?

SightRo- Автор вопроса
Mikhail
IActionResult

А если это сторонни й сервис, который не только в asp.net core используется?

SightRo
Я вот на этот вопрос и ищу ответ. То есть сервис о...

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

SightRo- Автор вопроса
Alex
А как часто такие обращения идут? )

По хорошему конечно никогда, но frontend'у доверять не стоит.

SightRo
Я вот на этот вопрос и ищу ответ. То есть сервис о...

На вкус и цвет все фломастеры разные. Если в проекте есть nullable reference - можно null, если нет или не хочется null, то исключения. Да, перф там не без оверхеда, но задача не вычислительная, и кидаются исключения не в промышленных масштабах

SightRo
А если это сторонни й сервис, который не только в ...

Какая разница? IActionResult Это просто интерфейс. Клиент получит ошибку или результат. Для результата возвращай return Ok(result), а если ошибка то return BadRequest()

Есть довольно популярная имплементация realworld.io с CQRS и MediatR'ом, там в хэндлере (условно говоря твой сервис) кидается RestException https://github.com/gothinkster/aspnetcore-realworld-example-app/blob/94e4616f8ecd48d5f42cd33f2bb0caac7a14417c/src/Conduit/Features/Articles/Details.cs#L40 По поводу перформанса хз, как-то пытался найти бэнчмарки, да так и не нашёл. Если у кого-то есть, дайте ссыль

Mikhail
Какая разница? IActionResult Это просто интерфейс....

Вы предлагает потом всем проектам, даже не asp.net, тащить в зависимости asp потом?

SomebodyOdd
Вы предлагает потом всем проектам, даже не asp.net...

Зачем тащить то? Есть rest api, какая разница, что он возращает. Клиенту фиолетово

Mikhail
Зачем тащить то? Есть rest api, какая разница, что...

Внимательнее вопрос посмотрите. Есть ASP.NET API, контроллер которого использует класс-сервис. Вопрос не что должно делать API, а что должен делать этот сервис-класс, который потом может быть использован вне ASP

SomebodyOdd
Внимательнее вопрос посмотрите. Есть ASP.NET API, ...

Ну значит я неправильно понял вопрос. Мне показалось, что нужно правильно обработать ошибку в контроллере.

SightRo- Автор вопроса

Отвечая на вопрос, большинство сошлось, что кидать exception неплохое решение. Но что по поводу четвертого варианта, какие у него проблемы? Потому что смотрится хорошо: дает достаточно информации контроллеру, чтобы сформировать правильный ответ, но не имеет проблем с производительностью.

SightRo
Отвечая на вопрос, большинство сошлось, что кидать...

Так ты через RestException тоже можешь нормальный ответ передать. Бойлерплейта меньше, чем result тащить откуда-то возможно издалека

SightRo- Автор вопроса
Иван
Так ты через RestException тоже можешь нормальный ...

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

SightRo
Отвечая на вопрос, большинство сошлось, что кидать...

Проблема с производительностью преувеличена. Там оверхед будет на порядки меньше чем то же обращение в базу. Если НАСТОЛЬКО не хочется - есть паттерн TrySomething()

SightRo- Автор вопроса
SomebodyOdd
Проблема с производительностью преувеличена. Там о...

Да, проблемы действительно нет. Но вопрос все-таки был про вариант с возвращение result объекта, который, как мне показалось, все упустили из виду. Хотел узнать причину. А так решение уже принято, будет кидаться исключение.

SightRo
Да, проблемы действительно нет. Но вопрос все-таки...

Потому что зачем целый Result object, когда достаточно bool или null? =)

SightRo
Да, проблемы действительно нет. Но вопрос все-таки...

Ты можешь вернуть result через RestException, типа throw new RestException(HttpStatusCode.NotFound, new { /* тут объект, который будет сконверчен в json и отдан на клиент */ }); Контроллер сам захэндлит эксепшен если что

SightRo- Автор вопроса
SomebodyOdd
Потому что зачем целый Result object, когда достат...

Ну такой result будет бесполезным. Но если добавить поле errors или взять готовую библиотеку, реализующую этот паттерн, то это даст куда больше полезной информации, чем bool.

Иван
Ты можешь вернуть result через RestException, типа...

А стоит ли в сервисе завязываться на rest api?

SightRo- Автор вопроса
Иван
Ты можешь вернуть result через RestException, типа...

Это уже лишние. Result и exception тут делают одну и ту же задачу - передают информацию об ошибке. Тут логичней выбрать что-то одно.

SightRo
Ну такой result будет бесполезным. Но если добавит...

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

SightRo- Автор вопроса
SomebodyOdd
И тем самым заменить общепринятый механизм исключе...

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

SightRo
Не согласен. Отсутствие ресурса, который запросил ...

null, потому что у него семантика "Значение отсутствует" и Nullable reference чтобы не подорваться на NRE. Ну, как хотите, закрыт так закрыт ¯\_(ツ)_/¯

Andrew Shurunov
А стоит ли в сервисе завязываться на rest api?

Смотря что за сервис. Если это сервис который разгружает контроллер (как в вопросе), то вполне можно Но вообще нет

Я делаю три варианта ошибок. Делаю на аппликейшн, лоджик и валидейшн. Аппликейшн это значит отвалился третий сервис (бд, апиха сторонняя, и ТД) показываем попап с ошибкой Лоджик это значит по логике энтити не может принять тот или иной стейт, тот же попап но с большей подробностью для юзера Ну и валидацию, просто словарь привязанный к полям формы Ещё есть NotFoundException, кидаю когда ничего не приходит из дал по запросу. На уровне апи я ловлю их в мидлваре и оборачиваю в 400 первые три экзепшена с типом для фронта и в 404 последний. Нюансов много ещё есть, но в целом я думаю картина ясна

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

Похожие вопросы

Обсуждают сегодня

Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
Коллеги, я тут для личных нужд пошел ставить MQTT сервер, пощупал mosquitto, но ужаснулся отсутствию такой банальности, как HTTP API для посмотреть список топиков. А тут что,...
Maksim Lapshin
9
#include <stdio.h> #include <stdlib.h> #include <time.h> void mass_first_generate(int mass[5][7]) {     for (int N = 0; N < 5; N++) {         for (int A = 0; A < 7; A++) {   ...
Чувак
6
Всем привет! Решаю 99 OCaml Problems и столкнулся со следующей проблемой (прошу палками не забивать, я OCaml практически не трогал до этого момента): open OUnit2 let create_...
К|/|pи/\/\ 6е3yглbIи
2
https://www.linkedin.com/posts/ugama-benedicta-kelechi-codergirl-103041300_mobiledevelopment-fluttertraining-handsonlearning-activity-7263445699227254784-IdHB?utm_source=share...
CoderGirl
16
Ну вот просто даже давайте вот как. Какой нибудь конкретный кейс, можете в пример привести, где бч работает и приносит прикладную пользу, а не просто что бы было? Не крипту.
Alexander Andreev
22
Точно, оно. У тебя там имена потоков выставляются?
Александр (Rouse_) Багель
11
возможно ли как-то передать в электрон или таури медиа поток с рендера 2д движка? двиг запускается как dll, а дальше надо как-то отправлять рендер кодировать не подходит, зр...
Kyle Nekto
7
Помогите пожалуйста. Делаю систему плагинов. Проблема сейчас в такая: плагины загружаются в основном потоке. FLibHandle := SafeLoadLibrary(FFileName) Но нужно еще выполнить фу...
Илья 🤣
10
объясните пожалуйста, почему функция не работает должным образом? вроде должно брать активное окно сравнивать его размер с размером экрана, и если есть совпадение = true прове...
JF
12
Карта сайта