Với tài liệu cốt lõi của ruby Exception
, từ đó tất cả các lỗi khác kế thừa, cho biết về#message
Trả về kết quả của việc gọi ra exception.to_s. Thông thường, nó trả về thông báo hoặc tên của ngoại lệ. Bằng cách cung cấp một phương thức to_str, các ngoại lệ sẽ đồng ý được sử dụng khi các Chuỗi được mong đợi.
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
Tôi sẽ chọn xác định lại to_s
/ to_str
hoặc trình khởi tạo. Đây là một ví dụ mà chúng tôi muốn biết, theo cách mà con người có thể đọc được, khi một dịch vụ bên ngoài không thực hiện được điều gì đó.
LƯU Ý: Chiến lược thứ hai bên dưới sử dụng các phương thức chuỗi khá rails, chẳng hạn như demodualize
, có thể hơi phức tạp và do đó có khả năng không khôn ngoan khi thực hiện trong một ngoại lệ. Bạn cũng có thể thêm nhiều đối số vào chữ ký phương thức, nếu bạn cần.
Ghi đè Chiến lược #to_s không phải #to_str, nó hoạt động theo cách khác
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
Đầu ra bảng điều khiển
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
Ghi đè #initialize Strategy
Đây là chiến lược gần nhất với các triển khai mà tôi đã sử dụng trong đường ray. Như đã đề cập ở trên, nó sử dụng demodualize
, underscore
và humanize
ActiveSupport
phương pháp. Nhưng điều này có thể dễ dàng được loại bỏ, như trong chiến lược trước.
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
Đầu ra bảng điều khiển
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
Công cụ Demo
Đây là một bản demo để hiển thị cách cứu và thông điệp của việc thực hiện ở trên. Lớp nâng cao các ngoại lệ là một API giả mạo đối với Cloudinary. Chỉ cần đưa một trong các chiến lược trên vào bảng điều khiển rails của bạn, sau đó là thao tác này.
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
. Nó rộng hơn mặc địnhrescue => e
mở rộng từStandardError
và bắt mọi thứ bao gồm Ctrl + C. Tôi sẽ làmrescue MyCustomError => e
.