失敗とエラーハンドリング
メソッドと例外の説明
以下のメソッドのいずれかを呼び出して、サービスを早期に終了させます:
fail_input!;fail_internal!;fail_output!;fail!;fail_result!.
これらのメソッドは例外をスローします。
上記のリストのうち、call経由の呼び出し後に処理できるのは以下のメソッドのみです:
fail!;fail_result!.
残りのメソッドは常に例外をスローします。
input、internal、outputアトリビュートの自動チェックも存在します。 これらのアトリビュートのバリデーション問題は対応する例外を発生させます。 この動作は以下のメソッドの呼び出しと同じです:
fail_input!;fail_internal!;fail_output!.
サービスのロジックは独自の例外をスローすることがあります(例: ActiveRecord::RecordInvalid)。 そのような場合はクラスレベルのfail_on!メソッドで処理します。
メソッド
メソッドfail_input!
inputアトリビュートの代わりに例外をスローします。
fail_input!メソッドはエラーテキスト、metaによる追加情報を受け取り、 inputアトリビュート名が必須です。
あらゆるサービス呼び出しでApplicationService::Exceptions::Input例外がスローされます。
make :check!
def check!
return if inputs.invoice_number.start_with?("AA")
fail_input!(
:invoice_number,
message: "Invalid invoice number",
meta: {
received_invoice_number: inputs.invoice_number
}
)
endApplicationService::Exceptions::Input例外が提供する情報の例:
exception.service # => <Actor: @class_name="InvoiceService::Check", @i18n_root_key="servactory">
exception.detailed_message # => Invalid invoice number (ApplicationService::Exceptions::Input)
exception.message # => Invalid invoice number
exception.input_name # => :invoice_number
exception.meta # => {:received_invoice_number=>"BB-7650AE"}メソッドfail_internal!
internalアトリビュートの代わりに例外をスローします。
fail_internal!メソッドはエラーテキスト、metaによる追加情報を受け取り、 internalアトリビュート名が必須です。
あらゆるサービス呼び出しでApplicationService::Exceptions::Internal例外がスローされます。
make :check!
def check!
return if internals.invoice_number.start_with?("AA")
fail_internal!(
:invoice_number,
message: "Invalid invoice number",
meta: {
received_invoice_number: internals.invoice_number
}
)
endApplicationService::Exceptions::Internal例外が提供する情報の例:
exception.service # => <Actor: @class_name="InvoiceService::Check", @i18n_root_key="servactory">
exception.detailed_message # => Invalid invoice number (ApplicationService::Exceptions::Internal)
exception.message # => Invalid invoice number
exception.internal_name # => :invoice_number
exception.meta # => {:received_invoice_number=>"BB-7650AE"}メソッドfail_output!
outputアトリビュートの代わりに例外をスローします。
fail_output!メソッドはエラーテキスト、metaによる追加情報を受け取り、 outputアトリビュート名が必須です。
あらゆるサービス呼び出しでApplicationService::Exceptions::Output例外がスローされます。
make :check!
def check!
return if outputs.invoice_number.start_with?("AA")
fail_output!(
:invoice_number,
message: "Invalid invoice number",
meta: {
received_invoice_number: outputs.invoice_number
}
)
endApplicationService::Exceptions::Output例外が提供する情報の例:
exception.service # => <Actor: @class_name="InvoiceService::Check", @i18n_root_key="servactory">
exception.detailed_message # => Invalid invoice number (ApplicationService::Exceptions::Output)
exception.message # => Invalid invoice number
exception.output_name # => :invoice_number
exception.meta # => {:received_invoice_number=>"BB-7650AE"}メソッドfail!
カスタムエラーを記述します。
fail!メソッドはエラーテキスト、metaによる追加情報、およびオプションのtypeを受け取ります。
デフォルトではtypeはbaseです。カスタム処理には任意の値を渡してください。
.call!経由の呼び出しはServactory::Exceptions::Failure例外をスローします。 .call経由の呼び出しはエラーを記録し、Resultで利用可能にします。
使用例
デフォルトタイプの最小限の例:
make :check!
def check!
return if inputs.invoice_number.start_with?("AA")
fail!(message: "Invalid invoice number")
endデフォルトタイプとメタデータの拡張例:
fail!(
:base,
message: "Invalid invoice number",
meta: {
invoice_number: inputs.invoice_number
}
)カスタムvalidationタイプとメタデータの例:
make :check!
def check!
return if inputs.email.include?("@")
fail!(
:validation,
message: "Email must contain @ symbol",
meta: {
field: :email,
provided_value: inputs.email
}
)
end提供される情報の例:
exception.detailed_message # => Invalid invoice number (ApplicationService::Exceptions::Failure)
exception.message # => Invalid invoice number
exception.type # => :base
exception.meta # => {:invoice_number=>"BB-7650AE"}validationタイプの例:
exception.detailed_message # => Email must contain @ symbol (ApplicationService::Exceptions::Failure)
exception.message # => Email must contain @ symbol
exception.type # => :validation
exception.meta # => {:field=>:email, :provided_value=>"user.example.com"}メソッドfail_result! 2.1.0以降
Resultを必要とし、内部でfail!メソッドを呼び出します。
あるサービスから現在のサービスへエラーを渡すコードを簡潔に記述するために設計されています。 例えば、APIサービスからアプリケーションサービスへの場合です。
fail_result!(service_result)上記のコードは以下と同等です:
fail!(
service_result.error.type,
message: service_result.error.message,
meta: service_result.error.meta
)メソッドfail_on! 2.5.0以降
指定された例外をキャッチします。
fail_on!メソッドは例外クラスを受け取り、オプションでメッセージテキストをカスタマイズします。
指定された例外の代わりにfail!が呼び出されます。 元の例外の情報はmeta経由でfail!に渡されます。
使い方
module ApplicationService
class Base < Servactory::Base
fail_on! ActiveRecord::RecordNotFound,
ActiveRecord::RecordInvalid
# ...
end
endメッセージテキストを以下のようにカスタマイズします:
fail_on! ActiveRecord::RecordNotFound,
with: ->(exception:) { exception.message }別の方法:
fail_on!(ActiveRecord::RecordNotFound) { |exception:| exception.message }