Результат работы сервиса
Сервис после вызова имеет результата работы, если до этого не было выкинуто исключение. Результат работы может быть успешный и провальный.
Успешный результат
Успешный результат — это результат работы сервиса, когда внутри все прошло без каких-либо проблем.
В таком случае этот пример:
service_result = UsersService::Accept.call(user: User.first)
Будет возвращать это:
# => <ApplicationService::Result @failure?=false, @success?=true, @user=..., @user?=true>
Провальный результат
Провальный результат — это результат работы сервиса, когда внутри произошла ожидаемая проблема. Под ожидаемой проблемой имеется ввиду что не было получено исключение, а возникшая проблема, например, была вызвана через один из fail!
методов.
Провальный результат работы сервиса может присутствовать только при вызове через .call
, метод. Это необходимо, например, чтобы иметь возможность обработать результат ответа от внешнего API.
Пример результата при возникшей проблеме:
# => <ApplicationService::Result @error=There is some problem with the user, @failure?=true, @success?=false>
Содержимое результата
Result
независимо от успеха или провала имеет набор данных.
При успешной работе доступны все output атрибуты, а также доступны методы хелперы success?
и failure?
, которые могут помочь определить сценарий для дальнейшей работы.
service_result = UsersService::Accept.call(user: User.first)
service_result.success? # => true
service_result.failure? # => false
При неудачной работе сервиса Result
будет также содержать error
с полным описанием ошибки.
service_result = UsersService::Accept.call(user: User.first)
service_result.success? # => false
service_result.failure? # => true
service_result.error
# => #<ApplicationService::Exceptions::Failure: There is some problem with the user>
Про неудачную работу сервиса вы можете более подробно узнать здесь.
Обработка результата
После вызова сервиса через call
вы можете обработать его результат.
Для этого существует два варианта — при помощи методов success?
и failure?
или при помощи хуков on_success
и on_failure
.
Методы
service_result = NotificatorService::Slack::Error::Send.call(...)
return if service_result.success? # или `unless service_result.failure?`
fail!(
message: "The message was not sent to Slack",
meta: { reason: service_result.error.message }
)
В метод failure?
можно передать тип. Подробнее про типы вы можете узнать здесь. Это дает возможность указать интересующий вас тип при обработке неудачного результата. По умолчанию type
имеет значение all
, что означает любой тип неудачи, включая ваши собственные типы.
service_result = NotificatorService::Slack::Error::Send.call(...)
return unless service_result.failure?(:all)
fail!(
message: "The message was not sent to Slack",
meta: { reason: service_result.error.message }
)
Хуки
Это альтернативный вариант обработки результата.
NotificatorService::Slack::Error::Send
.call(...)
.on_failure do |exception:|
fail!(
message: "The message was not sent to Slack",
meta: { reason: exception.message }
)
end
Метод on_success
имеет аргумент outputs
, который предоставляет доступ ко всем output атрибутам.
В метод on_failure
также можно передать тип.
NotificatorService::Slack::Error::Send
.call(...)
.on_success do |outputs:|
notification.update!(original_data: outputs.response)
end.on_failure(:all) do |exception:|
fail!(
message: "The message was not sent to Slack",
meta: { reason: exception.message }
)
end