Exception
다른 모든 오류가 상속 하는의 루비 코어 문서 에서 다음과 같이 설명합니다.#message
예외를 호출 한 결과를 반환합니다. 일반적으로 이것은 예외의 메시지 또는 이름을 반환합니다. to_str 메소드를 제공하면 예외가 문자열이 예상되는 곳에 사용되는 데 동의합니다.
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
재정의 to_s
/ to_str
또는 이니셜 라이저를 선택합니다. 다음은 외부 서비스가 어떤 작업을 수행하지 못했을 때 대부분 사람이 읽을 수있는 방식으로 알고 싶은 예입니다.
참고 : 아래의 두 번째 전략 demodualize
은 약간 복잡 할 수 있으므로 예외에서 수행하는 것이 현명하지 않을 수있는 과 같은 rails pretty string 메서드를 사용합니다 . 필요한 경우 메서드 서명에 더 많은 인수를 추가 할 수도 있습니다.
#to_str이 아닌 #to_s 전략을 재정의하면 다르게 작동합니다.
module ExternalService
class FailedCRUDError < ::StandardError
def to_s
'failed to crud with external service'
end
end
class FailedToCreateError < FailedCRUDError; end
class FailedToReadError < FailedCRUDError; end
class FailedToUpdateError < FailedCRUDError; end
class FailedToDeleteError < FailedCRUDError; end
end
콘솔 출력
begin; raise ExternalService::FailedToCreateError; rescue => e; e.message; end
# => "failed to crud with external service"
begin; raise ExternalService::FailedToCreateError, 'custom message'; rescue => e; e.message; end
# => "failed to crud with external service"
begin; raise ExternalService::FailedToCreateError.new('custom message'); rescue => e; e.message; end
# => "failed to crud with external service"
raise ExternalService::FailedToCreateError
# ExternalService::FailedToCreateError: failed to crud with external service
#initialize 전략 재정의
이것은 레일에서 사용한 구현과 가장 가까운 전략입니다. 전술 한 바와 같이, 그 용도 demodualize
, underscore
및 humanize
ActiveSupport
방법. 그러나 이것은 이전 전략 에서처럼 쉽게 제거 할 수 있습니다.
module ExternalService
class FailedCRUDError < ::StandardError
def initialize(service_model=nil)
super("#{self.class.name.demodulize.underscore.humanize} using #{service_model.class}")
end
end
class FailedToCreateError < FailedCRUDError; end
class FailedToReadError < FailedCRUDError; end
class FailedToUpdateError < FailedCRUDError; end
class FailedToDeleteError < FailedCRUDError; end
end
콘솔 출력
begin; raise ExternalService::FailedToCreateError; rescue => e; e.message; end
# => "Failed to create error using NilClass"
begin; raise ExternalService::FailedToCreateError, Object.new; rescue => e; e.message; end
# => "Failed to create error using Object"
begin; raise ExternalService::FailedToCreateError.new(Object.new); rescue => e; e.message; end
# => "Failed to create error using Object"
raise ExternalService::FailedCRUDError
# ExternalService::FailedCRUDError: Failed crud error using NilClass
raise ExternalService::FailedCRUDError.new(Object.new)
# RuntimeError: ExternalService::FailedCRUDError using Object
데모 도구
이것은 위 구현의 구조 및 메시징을 보여주는 데모입니다. 예외를 발생시키는 클래스는 Cloudinary에 대한 가짜 API입니다. 위의 전략 중 하나를 Rails 콘솔에 덤프 한 다음이를 따릅니다.
require 'rails' # only needed for second strategy
module ExternalService
class FailedCRUDError < ::StandardError
def initialize(service_model=nil)
@service_model = service_model
super("#{self.class.name.demodulize.underscore.humanize} using #{@service_model.class}")
end
end
class FailedToCreateError < FailedCRUDError; end
class FailedToReadError < FailedCRUDError; end
class FailedToUpdateError < FailedCRUDError; end
class FailedToDeleteError < FailedCRUDError; end
end
# Stub service representing 3rd party cloud storage
class Cloudinary
def initialize(*error_args)
@error_args = error_args.flatten
end
def create_read_update_or_delete
begin
try_and_fail
rescue ExternalService::FailedCRUDError => e
e.message
end
end
private def try_and_fail
raise *@error_args
end
end
errors_map = [
# Without an arg
ExternalService::FailedCRUDError,
ExternalService::FailedToCreateError,
ExternalService::FailedToReadError,
ExternalService::FailedToUpdateError,
ExternalService::FailedToDeleteError,
# Instantiated without an arg
ExternalService::FailedCRUDError.new,
ExternalService::FailedToCreateError.new,
ExternalService::FailedToReadError.new,
ExternalService::FailedToUpdateError.new,
ExternalService::FailedToDeleteError.new,
# With an arg
[ExternalService::FailedCRUDError, Object.new],
[ExternalService::FailedToCreateError, Object.new],
[ExternalService::FailedToReadError, Object.new],
[ExternalService::FailedToUpdateError, Object.new],
[ExternalService::FailedToDeleteError, Object.new],
# Instantiated with an arg
ExternalService::FailedCRUDError.new(Object.new),
ExternalService::FailedToCreateError.new(Object.new),
ExternalService::FailedToReadError.new(Object.new),
ExternalService::FailedToUpdateError.new(Object.new),
ExternalService::FailedToDeleteError.new(Object.new),
].inject({}) do |errors, args|
begin
errors.merge!( args => Cloudinary.new(args).create_read_update_or_delete)
rescue => e
binding.pry
end
end
if defined?(pp) || require('pp')
pp errors_map
else
errors_map.each{ |set| puts set.inspect }
end
rescue Exception => e
.rescue => e
에서 확장되는 기본값보다 광범위하며StandardError
Ctrl + C를 포함한 모든 것을 포착합니다. 나는 할 것이다rescue MyCustomError => e
.