Computer >> Máy Tính >  >> Lập trình >> Ruby

Thêm ngữ cảnh vào các lớp ngoại lệ

Gần đây, chúng tôi đã giao phiên bản 3.2 của honeybadger Ruby Gem, bao gồm một tính năng mới giúp thêm ngữ cảnh vào báo cáo lỗi của bạn dễ dàng hơn.

tl; dr

honeybadger gem hiện hỗ trợ xác định #to_honeybadger_context trên bất kỳ lớp ngoại lệ nào. Khi một trường hợp của ngoại lệ đó được nêu ra và báo cáo cho Honeybadger, ngữ cảnh của nó sẽ tự động được đưa vào báo cáo lỗi:

class MyError < StandardError
  attr_reader :custom_attribute

  def initialize(err, custom_attribute)
    @custom_attribute = custom_attribute
    super(err)
  end

  def to_honeybadger_context
    {
      custom_attribute: custom_attribute
    }
  end
end

raise MyError.new("Something went wrong", { foo: 'bar' })
# Honeybadger context will include:
# {
#   custom_attribute: {
#     foo: 'bar'
#   }
# }

Ngữ cảnh là gì?

Ngữ cảnh cho phép bạn gửi dữ liệu bổ sung đến Honeybadger khi xảy ra lỗi trong ứng dụng của bạn. Trong Rails, bạn có thể đặt ngữ cảnh cho yêu cầu hiện tại bằng cách sử dụng Honeybadger.context , được cung cấp bởi Ruby gem của chúng tôi:

Honeybadger.context({
  user_email: 'user@example.com'
})

Mọi lỗi xảy ra trong yêu cầu hiện tại (hoặc công việc nếu bạn đang chạy nhân viên chạy nền) sẽ có dữ liệu ngữ cảnh duy nhất của riêng nó.

Dữ liệu ngữ cảnh của bạn có thể là bất kỳ thứ gì, nhưng thường bao gồm những thứ như id người dùng hoặc địa chỉ email của người dùng hiện đang đăng nhập, một số dữ liệu POST thô hoặc tải trọng liên quan khác để hỗ trợ gỡ lỗi, id của công việc nền, v.v.

Bạn cũng có thể thêm ngữ cảnh cục bộ khi báo cáo lỗi theo cách thủ công:

Honeybadger.notify(exception, context: {
  user_email: 'user@example.com'
})

Sự thật thú vị:trong khi ngữ cảnh có thể là bất cứ thứ gì, Honeybadger có một vài khóa ngữ cảnh "đặc biệt". Ví dụ:nếu bạn bao gồm user_email với các báo cáo lỗi của bạn, Honeybadger sẽ tạo một báo cáo về những người dùng bị ảnh hưởng cho từng lỗi.

Thêm ngữ cảnh từ các trường hợp ngoại lệ

Một số ngữ cảnh cụ thể cho một ngoại lệ, chứ không phải là một yêu cầu. Ví dụ:giả sử chúng tôi đang thực hiện một yêu cầu HTTP bằng đá quý faraday:

require 'faraday'

conn = Faraday.new(:url => 'https://example.com') do |faraday|
  faraday.response :raise_error # Raises an error if the request isn't successful
  faraday.adapter  Faraday.default_adapter
end

response = conn.get('/does-not-exist') # => Faraday::ResourceNotFound

Đoạn mã trên nêu ra ngoại lệ sau:

Faraday::ResourceNotFound: the server responded with status 404

Honeybadger sẽ tự động báo cáo lỗi này (giả sử nó được định cấu hình để làm như vậy), nhưng nó sẽ không có bất kỳ thông tin nào về response sự vật. Thông tin này sẽ rất tốt nếu có, đặc biệt là đối với các lỗi máy chủ ít rõ ràng hơn, chẳng hạn như phản hồi 500.

Nhìn vào định nghĩa của Faraday::ResourceNotFound trên GitHub, chúng tôi thấy rằng nó thực sự là một loại ClientErrorClientError xác định một thuộc tính lưu trữ đối tượng phản hồi trên mỗi phiên bản.

Sử dụng thông tin này, chúng tôi có thể cứu tất cả các phiên bản của Faraday::ClientError và sử dụng Honeybadger.notify để thêm một số dữ liệu phản hồi vào ngữ cảnh:

begin
  response = conn.get('/does-not-exist')
rescue Faraday::ClientError => err
  Honeybadger.notify(err, context: {
    response_status:  err.response.status,
    response_headers: err.response.headers
  })
  # Additional error handling...
end

Điều này cho phép chúng tôi báo cáo các yêu cầu không thành công tới Honeybadger cùng với một số thông tin bổ sung về phản hồi.

Chúng tôi sử dụng mẫu này để thêm ngữ cảnh dành riêng cho ngoại lệ khi xảy ra lỗi và trong khi nó hoạt động, nó làm lộn xộn mã của chúng tôi với các câu lệnh cứu hộ và logic thông báo tùy chỉnh, điều này lộn xộn và thêm nhiều chi phí vào mã của chúng tôi. Tin tốt là:có một cách tốt hơn!

Tính năng mới:Ngữ cảnh cấp độ ngoại lệ

Thay vì báo cáo lỗi theo cách thủ công, ngữ cảnh hiện có thể được xác định trên chính lớp ngoại lệ và Honeybadger sẽ tự động nhận nó, bất kể lỗi cuối cùng được báo cáo ở đâu.

Xem lại ví dụ trước, thay vì thêm một rescue xấu xí , hãy cho phép báo cáo tích hợp của Honeybadger xử lý ngoại lệ:

response = conn.get('/does-not-exist') # => Faraday::ResourceNotFound

Thay vào đó, hãy thêm #to_honeybadger_context phương thức thành Faraday::ClientError , là một phương pháp đặc biệt mà Honeybadger kiểm tra khi có bất kỳ trường hợp ngoại lệ nào được báo cáo:

Faraday::ClientError.class_eval do
  def to_honeybadger_context
    {
      response_status:  err.response.status,
      response_headers: err.response.headers
    }
  end
end

Bằng cách thêm #to_honeybadger_context phương thức thành Faraday::ClientError , chúng tôi sẽ nhận được ngữ cảnh phản hồi bất cứ khi nào lỗi đó xảy ra, mà không làm lộn xộn mã của chúng tôi!