"로그 앤 스로우"가 안티 패턴으로 간주되는 이유는 무엇입니까? [닫은]


85

이 질문은 이 기사 에 대한 토론에서 촉발되었으며 좋은 답변을받지 못했습니다.

예외를 로깅 한 다음 다시 던지는 (물론 원래 스택 추적 유지)이 다른 방법으로 처리 할 수없는 경우 왜 나쁜 생각입니까?


에 대한 답변을 검색해보세요 softwareengineering.stackexchange.com
chharvey

답변:


121

나는 당신이 그것을 처리 할 수 ​​없다면 왜 그것을 잡는가? 그것을 처리 할 수있는 사람 (또는 처리 할 수밖에없는 사람)이 기록 할 가치가 있다고 느끼면 기록하도록 두지 않는 이유는 무엇입니까?

이를 포착하고 기록하고 다시 던지면 업스트림 코드가 이미 예외를 기록했음을 알 수있는 방법이 없으므로 동일한 예외가 두 번 기록 될 수 있습니다. 더 나쁜 것은 모든 업스트림 코드가이 동일한 패턴을 따르는 경우 예외가이를 포착하고 기록한 다음 다시 던지기로 결정한 코드의 각 수준에 대해 한 번씩 예외가 임의의 횟수로 기록 될 수 있습니다.

또한 예외를 던지고 잡는 것은 상대적으로 비용이 많이 드는 작업이므로이 모든 잡기와 다시 던지는 것은 런타임 성능에 도움이되지 않는다고 주장 할 수도 있습니다. 간결성 또는 유지 관리 측면에서 코드에 도움이되지도 않습니다.


자세한 내용은 Jeff의 답변에 대한 의견을 참조하십시오
Manu

8
예외를 기록하고 다시 던지는 이유는 이유를 좁히고 특정 메시지를 기록하기위한 것입니다.
Mike Argyriou 2014 년

11
답변 : 스택 추적의 다른 지점에서 사용할 수없는 스택의 현재 지점에서 사용할 수있는 유용한 디버그 정보가있을 수 있습니다.
rtconner

새로운 예외가 더 많은 정보 나 더 구체적으로 도움이되는 경우 catch 및 rethrowing이 때때로 도움이됩니다.
borjab

@rtconner가 언급 한 내용에 대해 설명하려면 : 비동기 코드에서 캐처가 thrower가 사용할 수있는 컨텍스트를 가지고 있지 않을 수 있습니다.
Nir Alfasi

53

예외를 포착하고 다시 던지는 엔티티가 호출 스택에 더 이상 기록되지 않는 정보가 포함되어 있다고 믿을만한 이유가 있다면 로그 앤 스로우는 좋은 패턴입니다. 이것이 발생할 수있는 몇 가지 이유는 다음과 같습니다.

  1. 예외는 응용 프로그램 계층 경계에서 포착되어 다시 발생할 수 있으며 권한있는 정보를 포함 할 수 있습니다. 데이터베이스 계층이 " 'users'필드에 중복 키 'fnord'를 추가하려고 시도"라는 예외를 허용하여 외부 애플리케이션 계층에 도달하도록하는 것은 좋지 않지만 (이는 사용자에게 노출 될 수 있음) 데이터베이스의 내부 부분에서 그러한 예외를 발생시키고 애플리케이션 인터페이스가이를 포착하고 안전하게 기록하고 다소 덜 설명적인 예외를 다시 발생시키는 데 유용 할 수 있습니다.
  2. 예외는 외부 계층이 로깅없이 처리 할 것으로 예상하는 것일 수 있지만 내부 계층은 로깅이 유용 할 수 있음을 암시하는 외부 계층이 모르는 것을 알고있을 수 있습니다. 대략적인 예로, 중간 응용 프로그램 계층이 한 서버에 연결을 시도하도록 프로그래밍되고 작동하지 않으면 다른 서버를 시도 할 수 있습니다. 유지 관리를 위해 서버가 다운되는 동안 애플리케이션 로그를 '연결 실패'메시지로 가득 채우는 것은 특히 애플리케이션의 관점에서 모든 것이 잘 작동하기 때문에 도움이되지 않을 수 있습니다. 연결 실패에 대한 정보를 서버와 관련된 로깅 리소스로 전달하는 것이 유용 할 수 있습니다. 그러면 모든 단일 연결 시도에 대한 로그가 아닌 서버가 작동 중지 된시기에 대한 보고서를 생성하도록 로그를 필터링 할 수 있습니다. .

4
# 1은 실제로 합리적인 일반적인 사용 사례이지만 OP는 "다시 던지기 (물론 원래 스택 추적 유지)"에 대해 명시 적으로 물었으므로 # 1은 정답이 아닙니다.
Geoffrey Zheng

@GeoffreyZheng : 원래 스택 추적을 안전하게 로깅하는 것이 "보존"으로 간주되는지 여부에 따라 달라집니다.
supercat

2
# 1과 관련하여 : e.getMessage()런타임 예외에 모든 종류의 민감한 정보가 포함될 수 있으므로 예외 콘텐츠 노출 (예 : UI에 / stacktrace 표시 및 REST 응답으로 전송)은 취약성 자체로 처리되어야합니다. # 2와 관련하여 : 클라이언트가 알기를 원하는 모든 정보 (+ 근본 원인)를 추가하여 예외를 다시 던질 수 있으며, 아무것도 기록 할 필요가 없습니다.
Nikita Bosik

@NikitaBosik : 예외가 클라이언트 측에 노출되어야하는지 여부에 관계없이이를 수행하는 애플리케이션은 '심층 보안'원칙에 따라 예외 메시지가 민감한 정보를 제거해야한다고 제안 할만큼 충분히 일반적입니다. 또한 외부 계층이 특정 유형의 예외를 로깅하지 않고 관심이있을 수있는 외부 엔터티에 정보를 전달하지 않고 폐기 할 것으로 예상하지 않는 경우 중간 계층이 정보를 추가하면 외부 계층이 무시할 것입니다. 아무것도.
supercat

20

가장 간단한 이유는 일반적으로 단일 최상위 처리기가이 작업을 수행하므로이 예외 처리로 코드를 오염시킬 필요가 없다는 것입니다.

교차 절단 우려 주장은 기본적으로 당신과 상관없는 오류를 처리하는 데 시간 낭비라는 것입니다. 적절한 핸들러를 찾을 수있을 때까지 오류가 호출 스택에 버블 링되도록하는 것이 훨씬 좋습니다.

제 생각에 예외를 포착해야하는 유일한 경우는 결과로 유용한 일을 할 수있을 때입니다. 단순히 로그를 잡는 것은 유용하지 않습니다. 그 작업을 더 많이 중앙 집중화 할 수 있기 때문입니다.


1
이 작업을 수행하는 단일 최상위 처리기가 있어야한다는 데 동의합니다. 그러나 제 생각에는 최상위 레벨 핸들러는 "로그 앤 스로우"여야합니다. 그래서 논쟁은 어떤 지점에서 "로그하고 던지는"것입니다.
Manu

@Manu, 요점은 단일 처리기 (중앙 집중식)이면 괜찮다는 것입니다. 코드를 복제하는 경우에는 좋지 않습니다. 그 이상은 없다고 생각합니다!
Jeff Foster

5
@Manu-이 경우 최상위 처리기는 무엇입니까? 던질 수있는 것이 있다면 실제로 최상위 핸들러가 아닌 것 같습니다. 그리고 런타임 환경 자체까지 예외를 다시 던지고 싶지는 않습니다. 그러면 대부분의 응용 프로그램이 중단됩니다.
aroth

1
@aroth : 당신이 말하는 것은 "log and handle"(당신이 최상위 수준의 핸들러라면) 또는 그렇지 않다면 "Do not log and throw (or handle 달리)"입니다. 지적 해 주셔서 감사합니다.
Manu

9

IMO 로그 앤 스로우는 최소 서프라이즈 원칙에 대한 명백한 위반입니다.

예외가 호출 스택에서 제대로 처리되는 경우 오류 로그 항목이 전혀 가치가 없을 수 있습니다. 그리고 오류 로그 항목을 찾는 것이 혼란 스럽습니다.


비 오류 로그는 어떻습니까?
Su Zhang

6
@SuZhang 귀하의 질문을 이해하지 못합니다. 오류가 없으면 던질 것이 없습니다. 물론 비 오류 로그를 작성할 수 있으며 작성해야합니다.
Bastian Voigt 2014
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.