Rails의 예외적인 동작 마무리하기

6599 단어 railsruby

초기화



지난 포스트에서 우리는 Rails 5와 Rails 6 사이에 일관성이 없는 동작을 발견했습니다. Rails 5에서 RuntimeError 예외로부터 구한 후 컨트롤러에서 ActiveRecord::RecordNotFound를 발생시키면 여전히 404 HTTP 상태 코드를 반환했습니다. Rails 6에서 상태 코드는 500입니다.

우리는 주위를 둘러보았고 ExceptionWrapper class 에 관심 영역을 분리했다고 생각합니다.

래퍼 재방문



우리는 래퍼를 만드는 것이 무엇인지 조사했고 항상 그것을 전달하고 있다는 것을 발견했습니다RuntimeError. 필요한 휴식을 취한 후 코드를 다시 읽기 시작하고 거의 즉시 transformation이 표시됩니다.

def initialize(backtrace_cleaner, exception)
  @backtrace_cleaner = backtrace_cleaner
  @exception = original_exception(exception)
end


전달된 예외가 수정됩니다. 이것을 봅시다 original_exception method .

def original_exception(exception)
  if @@rescue_responses.has_key?(exception.cause.class.name)
    exception.cause
  else
    exception
  end
end

RuntimeError 예외를 처리한 결과 ActiveRecord::RecordNotFound가 발생했음을 기억하십시오. RecordNotFound 예외는 RuntimeErrorcause 입니다. 우리는 이전에 RecordNotFound가 ActiveRecord의 railtie에서 @@rescue_responses에 추가되었음을 발견했습니다.

예외의 원인은 해시에 있으므로 이니셜라이저에서 @exception 변수로 원인을 설정합니다. 그 원인은 RecordNotFound 이며 RecordNotFound 예외는 404 상태 코드를 반환해야 합니다.

이제 404가 반환되는 이유를 설명할 수 있습니다!

선물하기(Rails 6 Redux)



이제 Rails 5의 동작을 처리할 수 있습니다. 그러나 이 조사는 Rails 5와 Rails 6에서 다르다는 것을 알았기 때문에 시작되었습니다. Rails 6 에서 ExceptionWrapper 이니셜라이저를 확인해 보겠습니다.

def initialize(backtrace_cleaner, exception)
  @backtrace_cleaner = backtrace_cleaner
  @exception = exception
end


더 이상 original_exception 를 검색하지 않습니다. 그렇다고 해서 모든 이야기가 나오는 것은 아닙니다. status code 을 요청할 때 @exception 를 사용하지 않습니다. 대신, 이제 unwrapped_exception ~ investigate 가 있습니다.

def unwrapped_exception
  if wrapper_exceptions.include?(exception.class.to_s)
    exception.cause
  else
    exception
  end
end

rescue_responses 를 살펴보는 대신 wrapper_exceptions 를 살펴보고 있습니다.
특히 예외적으로 행동합니다.

예외가 ActionView::Template::Error 인 경우 예외의 원인에 따라 상태 코드를 조회하십시오. 그렇지 않으면 예외 자체를 기반으로 결정합니다.
RuntimeError 는 이 wrapper_exceptions 목록에 없으므로 원인( ActiveRecord::RecordNotFound )을 사용하여 상태 코드를 확인하지 않습니다. 우리는 RuntimeError 자체를 사용합니다. rescue_responses 에서는 특별한 처리가 없으므로 500 HTTP 상태 코드가 반환됩니다.

목록 감사 카드



이 변경을 수행하는 에는 다음을 포함하여 이 시나리오에 대한 매우 정확한 설명이 포함되어 있습니다.

When the cause is mapped to an HTTP status code the last exception is unexpectedly uwrapped



이 문제를 해결해 주신 commit 감사합니다!

This post originally published on The Gnar Company blog.

좋은 웹페이지 즐겨찾기