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 ответов

8 просмотров

Если в нормальной работе сервиса не ожидаются несуществующие 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 MySuperDuperConcat(const a: array of AnsiString): AnsiString; Как мне в её теле сделать вот так? Result:=Concat(a); А не грустный вариан...
notme
15
type TObj = object procedure Init; virtual; end; TObj1 = object(TObj) procedure Init; override; end; procedure TObj1.Init; begin inherited; end; procedur...
Alexander 👋
29
Есть какой-нибудь для Delphi/FPC T*Compression(Decompression)Stream на базе LZ4/Zstd/любой другой быстрый(и хорошо сжимающий) алгоритм А ещё лучше в pure pascal А ещё лучше од...
notme
48
А чем вам питонисты не угодили?😂
.
79
Можно ли загрузить скрипт py в бота чтобы он работал по нему? как это сделать?
huskadam #RCC Фанат? @hitlerpvp
13
Всем здравствуйте! Я хотел узнать сколько стоит средняя месячная зарплата у Electron js разработчиков? Мне очень это важно и нужно, плиз помогите узнать эту инфу! Для Джунио...
U.K.
10
Всем привет, написал код ниже, но он выдает сегфолт, в чем причина? #include <stdio.h> #include <stdlib.h> #include <string.h> struct product { char *name; float price; };...
buzz базз
77
А дин типизация это хорошо или плохо?
Alexey
12
Язык Си можно выучить за день? По книжке ANSI C на 230 страниц
Vincent Vegan
29
Исходники плюс документация? Вы гоните)) демок хватит всем
zamtmn
11
Карта сайта