NoMethodError: undefined method `to_i' for an instance of ActionController::Parameters
Fix Plan: NoMethodError: undefined method `to_i' for an instance of ActionController::Parameters
선택된 fix track = 단기 개선 (1주 이내). 그 중 저비용 대안(narrow rescue_from NoMethodError)을 구현한다. 즉시 조치 / 장기 개선 항목은 범위에서 제외한다.
Changes#
tesla: app/controllers/concerns/client_error_controller.rb#
- What:
rescue_from NoMethodError, with: :invalid_parameter_type_400_error를 추가하고, 새 handlerinvalid_parameter_type_400_error(exception)를 정의한다. handler 는exception.message가ActionController::Parameters를 포함할 때만raise_error(400, ...)로Cupix::Errors::Parameter(codeARG10000, reasonInvalid parameter) 매핑한다. 그 외NoMethodError(진짜 nil-ref / 코드 결함) 는raise exception으로 재-raise 하여 기존대로 500 으로 노출한다. - Why: 클라이언트가 스칼라 파라미터를 nested 형태(
current_pano_id[a]=1)로 보내면 Rails 가 이를ActionController::Parameters로 파싱하고, 산재한params[...].to_i/.split호출이NoMethodError를 raise 한다. 이 예외는RuntimeError계열이 아니고 rescue_from 목록에도 없어 unhandled 500 으로 흐른다 (root cause = malformed client input 의 상태코드 mis-mapping).ActionController::Parameters메시지에 한정해 400 으로 매핑하면 노이즈를 제거하면서 실제 프로그래밍 버그(다른 nil 참조 NoMethodError)는 500 으로 계속 드러난다. - Lines: rescue_from 블록에 1줄 추가 (line 29 부근), private 위 handler 메서드 1개 추가 (약 8줄).
tesla: spec/controllers/concerns/client_error_controller_spec.rb#
- What:
invalid_parameter_type_400_errordescribe 블록 추가. (1)ActionController::Parameters메시지의NoMethodErrorraise → 400 +ARG10000+ reasonInvalid parameter검증. (2) 무관한 메시지의NoMethodError(예:undefined method 'foo' for nil) raise → 400 으로 삼켜지지 않고 재-raise 되어 컨트롤러 밖으로 전파됨을 검증 (회귀 방지: 진짜 버그가 숨겨지지 않음). - Why: narrow 매핑의 두 경로(match → 400, non-match → re-raise)를 명시적으로 고정하여 리뷰어가 의도를 확인하고 향후 회귀를 방지.
- Lines: 신규 describe 블록 약 30줄.
Acceptance Criteria#
-
client_error_controller.rb에rescue_from NoMethodError가 정확히 1개 존재하고, handler 가ActionController::Parameters메시지에만 400 을 반환한다. - handler 가 non-matching
NoMethodError를raise exception으로 재-raise 한다 (broad swallow 아님). - 신규 spec 2개 케이스(match→400, non-match→re-raise)가 통과한다.
-
ruby -c app/controllers/concerns/client_error_controller.rb문법 통과. - 기존
value_too_long_400_error등 다른 handler 동작 변경 없음 (diff 이 rescue_from 추가 + 새 메서드에 한정).
Tests#
- 기존 테스트:
spec/controllers/concerns/client_error_controller_spec.rb(기존 value_too_long 케이스 유지). - 신규 테스트: 위 spec 파일에
invalid_parameter_type_400_errordescribe 블록 2 케이스 추가.