많은 예외 메시지에 유용한 세부 정보가 포함되지 않은 이유는 무엇입니까?


220

예외 메시지에 유용한 세부 정보가 포함되어야 한다는 일정 정도의 동의가있는 것 같습니다 .

시스템 구성 요소의 많은 예외가 유용한 세부 정보를 포함하지 않는 이유는 무엇입니까?

몇 가지 예 :

  • .NET의 List인덱스 액세스는 ArgumentOutOfRangeException않습니다 하지 나에게 시도하고 유효 된 인덱스 값을 알 않으며 나에게 허용 된 범위를 알려 않습니다.
  • 기본적으로 MSVC C ++ 표준 라이브러리의 모든 예외 메시지는 전혀 쓸모가 없습니다 (위와 같은 맥락에서).
  • 말하고 .NET에서 오라클 예외는, "테이블이나 뷰 찾을 수 없습니다"(의역),하지만 어느 하나를.

따라서 나에게는 대부분 예외 메시지에 유용한 세부 정보가 충분 하지 않은 것 같습니다 . 내 기대치가 맞지 않습니까? 나는 이것을조차 알지 못하는 예외를 잘못 사용하고 있습니까? 아니면 내 인상이 잘못되었을 수도 있습니다. 대부분의 예외 실제로 유용한 세부 정보를 제공합니까?


59
보안 전문가의 입장에서 볼 때 "오류 메시지에는 시스템 내부에 대한 세부 정보가 포함되어서는 안됩니다"라는 것이 일반적입니다.
Telastyn

118
@Telastyn : 시스템이 공격자에게 개방 된 경우에만 해당됩니다. 예를 들어 웹 서버를 실행중인 경우 최종 사용자에게 잘못된 오류 메시지를 제공하려고하지만 최종 사용자에게 매우 자세한 오류 메시지가 기록되기를 원합니다. 그리고 사용자가 공격자가 아닌 클라이언트 측 소프트웨어에서는 오류 메시지를 가능한 한 자세하게 설명해야합니다. 따라서 문제가 발생하여 버그 보고서를받을 때 작업 할 정보가 많이 있습니다. 많은 시간이 필요하기 때문에 가능한 한.
메이슨 휠러

9
@ Snowman : 클라이언트 측 소프트웨어 인 경우 사용자가 액세스 할 수없는 것은 무엇입니까? 기계의 소유자는 기계를 소유 하며 무엇이든 얻을 수 있습니다.
메이슨 휠러


6
당신이 갖고 싶은 추가 정보가 항상 있습니다. 나는 당신이 모범으로 제시 한 메시지가 아주 좋다는 것을 알았습니다. 그들과 함께 문제를 디버깅 할 수 있습니다. "오류 0x80001234"(Windows Update에서 영감을받은 예)보다 훨씬 낫습니다.
usr

답변:


204

예외의 개념이 소프트웨어 공학 분야에서 아직 성숙하지 못했기 때문에 예외에는 유용한 세부 사항이 포함되어 있지 않으므로 많은 프로그래머가 예외를 완전히 이해하지 못하므로 제대로 처리하지 못합니다.

예. IndexOutOfRangeException범위를 벗어난 정확한 인덱스와 던져 질 당시 유효한 범위를 포함해야하며, 그렇지 않은 .NET 런타임 작성자를 대신하여 생각할 수 있습니다. 예, Oracle의 table or view not found예외에는 발견되지 않은 테이블 또는 뷰의 이름이 포함되어야하며, 다시 책임이있는 사람을 대신하여 해당 테이블 또는 뷰 이름을 볼 수 없다는 사실이 포함되어야합니다.

대체로 혼동은 예외에 사람이 읽을 수있는 메시지가 포함되어야한다는 잘못된 생각의 원래 아이디어에서 비롯되며, 이는 예외가 무엇인지에 대한 이해 부족으로 인한 것이므로 악순환입니다.

사람들은 예외에 사람이 읽을 수있는 메시지가 포함되어야한다고 생각하기 때문에 예외에 의해 전달되는 모든 정보도 사람이 읽을 수있는 메시지로 형식화해야하며 모든 사람이 읽을 수있는 메시지를 작성하는 것은 지루합니다. 코드를 작성하거나, 그렇게하는 것은 훔쳐 보는 눈이 메시지를 볼 수있는 모든 것에 불가피한 양의 정보를 누설 할 수 있다고 두려워합니다. (다른 답변에서 언급 한 보안 문제)

그러나 문제의 진실은 예외가해야하기 때문에 그들이 그것에 대해 걱정하지 말아야한다는 것입니다 없는 사람이 읽을 수있는 메시지를 포함하고있다. 예외는 프로그래머 만보고 처리해야하는 것입니다. 사용자에게 장애 정보를 제시 할 필요가있는 경우, 이는 매우 높은 수준에서 정교한 방식으로, 통계적으로 말하면 영어가 아닐 수있는 사용자의 언어로 수행되어야합니다.

따라서 프로그래머에게 예외의 "메시지"는 예외의 클래스 이름 이며 예외 와 관련된 다른 정보는 예외 객체의 (최종 / 읽기 전용) 멤버 변수에 복사해야합니다. 바람직하게는, 모든 가능한 작은 비트. 이런 식으로, 메시지가 생성 될 필요가 없어야하므로 엿보는 눈으로 볼 수 없습니다.

아래 의견에서 Thomas Owens가 표시 한 문제를 해결하려면 다음을 수행하십시오.

물론 어떤 수준에서는 예외에 관한 로그 메시지를 작성 하게됩니다 . 그러나 스택 추적이없는 예외 로그 메시지는 쓸모가 없지만 다른 한편으로는 사용자에게 전체 예외 스택 추적을 표시하지 못하게하는 것입니다. 여기서도 우리의 문제는 우리의 관점이 전통적인 관행에 의해 왜곡된다는 것입니다. 로그 파일은 전통적으로 평범한 텍스트였으며, 우리의 규율이 초기 단계에 있었지만 더 이상은 아닐 수 있습니다. 보안 문제가있는 경우 로그 파일은 이진 및 / 또는 암호화되어야합니다.

이진 또는 일반 텍스트이든, 로그 파일은 애플리케이션이 디버그 정보를 직렬화하는 스트림으로 생각해야합니다. 이러한 스트림은 프로그래머에게만 해당되며 예외에 대한 디버깅 정보를 생성하는 작업은 예외를 디버그 로그 스트림에 직렬화하는 것만 큼 간단해야합니다. 이 방법으로 로그를 보면 예외 클래스 이름을 볼 수 있습니다. (이미 언급했듯이 모든 실제적인 목적을 위해 "메시지"입니다.) 각 예외 멤버 변수는 관련된 모든 것을 설명합니다. 실습에 포함하고 로그 전체 스택 추적. 이 프로세스에서 사람이 읽을 수있는 예외 메시지의 형식이 눈에 띄게 누락 된 방법에 유의하십시오 .

추신

이 주제에 대한 내 생각 중 몇 가지 가이 답변에서 찾을 수 있습니다 . 좋은 예외 메시지를 작성하는 방법

PPS

이진 로그 파일에 대한 나의 제안으로 많은 사람들이 똑딱 거리고있는 것처럼 보이므로 여기서 제안 하는 것은 로그 파일 이진 이어야 한다는 것이 아니라는 것을 더 명확하게하기 위해 답을 다시 수정 했습니다. 필요한 경우 로그 파일 이진 파일 수 있습니다.


4
.NET Framework의 예외 클래스 중 일부를 살펴 봤으며 프로그래밍 방식으로 이러한 종류의 정보를 추가 할 수있는 많은 기회가 있음이 밝혀졌습니다. 그래서 나는 그 질문이 "왜 안 되겠는가"로 해결되는 것 같습니다. 그러나 "인간이 읽을 수있는"내용은 +1입니다.
Robert Harvey

7
예외에는 사람이 읽을 수있는 구성 요소가 포함되어서는 안된다는 데 동의하지 않습니다. 어떤 수준에서는 예외와 관련된 로그 메시지를 만들 수 있습니다. 스택 추적을 사용자가 읽을 수있는 로그 파일에 로깅하면 노출하고 싶지 않은 구현 세부 정보가 노출되므로 사람이 읽을 수있는 메시지를 기록해야한다고 주장합니다. 오류가 포함 된 로그 파일이 표시되면 개발자는 디버깅을 시작하고 예외가 발생할 수있는 시작점이 있어야합니다. 사람이 읽을 수있는 구성 요소는 구현을 포기하지 않고 적절히 상세해야합니다.
Thomas Owens

44
프로그래머는 인간이 아닌가? 내 동료를 보면 이것은 내가 한동안 가지고 있었던 몇 가지 의혹을 확인시켜줍니다.
gbjbaanb

51
다시 말하지만, 소프트웨어가 클라이언트 측인 한 사용자가 전체 스택 추적을 볼 수있게하는 데 아무런 문제가 없습니다 . 내가 작업 한 모든 전문 소프트웨어 프로젝트와 대부분의 아마추어 프로젝트에는 현재 실행중인 모든 스레드의 전체 스택 추적을 포함하여 처리되지 않은 예외가 발생했을 때 전체 오류 덤프를 생성하는 로깅 시스템이 포함되어 있습니다. 방법. 그리고 사용자 는 오류 메시지를 우리에게 다시 보내기 위해 필요 하기 때문에 (간단히 유용 합니다. ) 필요 하기 때문에 원하는 때마다 그것을 볼 수 있습니다 ! 그게 뭐가 문제 야?
메이슨 휠러

13
바이너리 전용 로그 파일에 대해서는 확신이 없습니다 . 주로 systemd에 대한 나의 경험 때문입니다. 이 로그를 볼 수있는 특별한 도구는 매우 혼란스럽고 셰익스피어 원숭이위원회가 디자인 한 것으로 보입니다. 웹 응용 프로그램의 경우 예외를 가장 먼저 본 사람은 종종 sysadmin 이며, 수정해야 할 부분 (예 : 디스크 공간 부족)인지 다시 확인하려고합니다. 개발자들에게.
Michael Hampton

46

시스템 구성 요소의 많은 예외가 유용한 세부 정보를 포함하지 않는 이유는 무엇입니까?

내 경험상 예외에 유용한 정보가 포함되지 않은 데에는 여러 가지 이유가 있습니다. 이러한 종류의 이유는 시스템 구성 요소에도 적용되기를 기대하지만 확실하지 않습니다.

  • 보안에 중점을 둔 사람들은 예외를 정보 유출의 원천으로 간주합니다 ( :) . 예외의 기본 동작은 해당 정보를 사용자에게 표시하는 것이므로 프로그래머는 때때로주의를 기울여야합니다.
  • C ++에서 catch 블록 (좋은 메시지를 만들기위한 컨텍스트 중 일부가있는 곳)에 메모리를 할당하지 않는다는 주장을 들었습니다. 이러한 할당은 관리하기가 어렵고 더 나쁜 경우 메모리 부족 예외가 발생하여 앱이 중단되거나 메모리 누수가 발생할 수 있습니다. 메모리를 할당하지 않고 예외를 멋지게 포맷하는 것은 어렵고 프로그래머가하는 것처럼 언어간에 마이그레이션이 수행 될 수 있습니다.
  • 그들은 모른다. 내 말은, 거기에 있는 코드가없는 시나리오 에는 무엇이 잘못되었는지 생각은. 코드를 모르면 알 수 없습니다.
  • 현지화 문제로 인해 영어 만 지원하는 직원들만 읽을 수있는 예외를 제외하고는 영어로만 문자열을 시스템에 넣지 못하는 곳에서 근무했습니다.
  • 어떤 곳에서는 예외가 더 많은 주장과 같이 사용되는 것을 보았습니다. 개발 중에 무언가가 이루어지지 않았거나 한 곳에서 변경이 있었지만 다른 곳에서는 변경되지 않았다는 분명하고 큰 메시지를 제공하기 위해 존재합니다. 좋은 메시지가 중복되거나 단순히 혼란 스러울 정도로 독특합니다.
  • 사람들은 게으르고 프로그래머보다 더 많습니다. 우리는 행복한 길보다 예외적 인 길에 훨씬 적은 시간을 소비하며 이는 부작용입니다.

내 기대치가 맞지 않습니까? 내가 이것을조차 알지 못하는 예외를 잘못 사용하고 있습니까?

킨다? 예외는 좋은 메시지를 가져야하지만 예외 이기도 합니다. 코딩 할 때 일종의 대화 형 피드백 메커니즘으로 사용하지 않고 예외적 인 조건을 피하기 위해 코드를 설계하거나 예외적 인 조건을 처리하는 코드를 작성 (메시지 무시)하는 데 시간을 소비해야합니다. 디버깅 목적으로 사용할 수는 없지만 대부분의 상황에서 최소한으로 유지해야합니다. 당신이이 문제를 눈치 채게함으로써 당신이 그것들을 막기 위해 충분한 일을하고 있지 않다고 걱정하게됩니다.


나는 이것이 C로 태그되어 있음을 알고 있지만 일부 문단은 예외 기반 오류 처리 보고 에 크게 의존 할 수 있기 때문에 마지막 단락이 모든 언어에 적용되는 것은 아니라고 덧붙여 야합니다 .
Lilienthal

1
@Lilienthal와 같은? 내가 잘 알고있는 언어는 그런 종류의 일을 정기적으로하지 않습니다.
Telastyn

1
나는이 답변에 좋은 내용이 많이 있다고 생각하지만, "그들은해야 할 것"이라는 결론을 피할 수 있습니다.
djechlin

3
감사. 귀하의 우려는 근거가 없습니다 (나는 희망합니다 :-). 그러나 때마다 내가 그 단위 테스트에 잘못된 또는 로그 파일이 정보가 부족하기 때문에 코드를 분석하는 여분의 시간을 보내고 무엇을 추가 분 추적을 보내고, 나는에 의해 짜증 조금있어 피할 일부 메시지 :-)의 똥차
마틴 바

@Telastyn SAP의 독점 ABAP는 예외 클래스 구문에 메시지를 포함 할 수 있습니다. 기본적으로 동적 (다국어) 메시지와 함께 프로그램 상태 (성공, 실패, 경고)를 사용자에게보고하는 객체입니다. 나는 이런 종류의 것들이 얼마나 널리 퍼져 있는지 알지 못하거나 언어로 장려된다면 가능하지만 적어도 (공회 적으로) 일반적인 관행이있는 곳이 있다는 것을 인정합니다.
Lilienthal

12

나는 C # 경험이 많지 않거나 C ++을 구체적으로 가지고 있지는 않지만 이것을 말할 수 있습니다. 개발자가 작성한 예외는 10 번 중 9 번이 발견 할 수있는 일반적인 예외보다 더 유용합니다.

이상적으로 예, 일반적인 예외는 오류가 발생한 이유를 정확하게 알려주고 쉽게 해결할 수는 있지만 실제로는 다양한 종류의 예외를 throw 할 수있는 여러 클래스가있는 대규모 응용 프로그램에서 같은 종류의 예외가 있으면 기본 메시지에 의존하는 것보다 오류 반환에 대한 자체 출력을 작성하는 것이 항상 더 중요합니다.

이것은 많은 사람들이 지적하기 때문에, 일부 응용 프로그램은하지 않습니다, 어떻게해야입니다 원하는 그들은 사용자가 보안상의 이유로, 볼하거나 혼란을 방지하기 위해 원하지 않는 오류 메시지를 던져.

대신, 설계에서 응용 프로그램에 어떤 유형의 오류가 발생할 수 있으며 (오류가 항상있을 수 있음) 문제를 식별하는 데 도움이되는 오류 메시지를 작성해야합니다.

유용한 오류 메시지를 예상 할 수 없기 때문에 항상 도움이되지는 않지만 장기적으로 자신의 응용 프로그램을 더 잘 이해하는 첫 번째 단계입니다.


7

문제는 "시스템 구성 요소"(일명 표준 라이브러리 클래스)에 의해 발생하는 많은 예외가 유용한 세부 사항을 포함하지 않는 이유를 구체적으로 묻습니다.

불행히도 대부분의 개발자는 표준 라이브러리에 핵심 구성 요소를 쓰거나 상세한 설계 문서 또는 기타 설계 이론적 근거가 반드시 공개되지는 않습니다. 다시 말해, 우리는 결코 확실하지 않을 수 있습니다.

그러나 자세한 예외 정보가 바람직하지 않거나 중요한 이유에 대해 명심해야 할 두 가지 핵심 사항이 있습니다.

  1. 어떤 식 으로든 코드를 호출하여 예외를 사용할 수 있습니다. 표준 라이브러리는 예외가 사용되는 방식을 제한 할 수 없습니다. 구체적으로 사용자에게 표시 될 수있다. 범위를 벗어난 배열 인덱스를 고려하십시오. 이렇게하면 공격자에게 유용한 정보가 제공 될 수 있습니다. 언어 디자이너는 응용 프로그램이 예외를 어떻게 사용하는지 또는 어떤 유형의 응용 프로그램 (예 : 웹 응용 프로그램 또는 데스크톱)을 사용하는지 알지 못하므로 정보를 남기지 않는 것이 보안 측면에서 더 안전 할 수 있습니다.

  2. 사용자 에게는 예외 표시 되지 않아야 합니다. 대신, 친숙한 오류 메시지를 표시하고 공격자가 액세스 할 수없는 위치에 예외를 기록하십시오 (해당되는 경우). 오류가 확인되면 개발자는 코드를 통해 디버그하여 스택 프레임과 논리 경로를 검사해야합니다. 이 시점에서 개발자에게는 예외가 기대했던 것보다 많은 정보가 있습니다.


3
1.이 기준에 따라 정보가 무엇인지 ( "인덱스 범위를 벗어남", 스택 추적) 표시되지 않는 것 (인덱스 값)은 비교적 임의적 인 것으로 보입니다. 2. 관련 동적 값을 알고 있으면 디버깅이 훨씬 빠르고 쉬워 질 수 있습니다. 예를 들어, 문제가 실패한 코드에 대한 가비지 입력인지 또는 올바른 입력을 올바르게 처리하지 못하는 코드인지를 즉시 알려줍니다.
Ben Aaronson

@ BenAaronson 예외의 ID / 클래스는 오류 유형을 알려줍니다. 내 요점은 보안을 위해 세부 사항을 생략 할 수 있다는 것입니다 (즉, 특정 값으로 인해 오류가 발생했습니다). 이 값은 사용자 입력으로 다시 추적 가능하여 공격자에게 정보를 표시 할 수 있습니다.

@Snowman 전체 스택 추적을 사용할 수 있고 인덱스 번호가없는 경우 보안이 고려 대상이라고 생각하지 않습니다. 물론 버퍼 오버플로를 탐지하는 공격자는 이해하지만, 많은 예외는 (예를 들어 Oracle 테이블을 찾지 못한) 상당히 안전한 데이터를 제외합니다.
gbjbaanb

@gbjbaanb 누가 우리에게 전체 스택 추적을 사용자에게 보여줄 필요가 있다고 말합니까?

1
통찰력을 공유해 주셔서 감사합니다. 개인적으로, 나는 안보 논쟁이 완전한 오류라고 생각하지 않으며, 그것은 이론적 근거 일 수 있습니다.
Martin Ba

4

먼저 diag 메시지에 4 초 안에 정확한 코드 라인과 하위 명령을 제공하는 정보가 담겨 있어도 버블을 터뜨릴 수 있습니다. 사용자가 절대로 적어 놓거나 지원 담당자에게 전달하지 않을 가능성이 있습니다. "당신은 위반에 대해 뭐라고 말했는지 ... 복잡해 보이는지 모르겠습니다!"

저는 30 년 넘게 소프트웨어를 작성하고 다른 소프트웨어의 결과를 지원해 왔으며, 개인적으로 예외 메시지의 현재 품질은 최종 결과가 모델에 어떻게 적용되는지에 관계없이 사실상 보안과 아무런 관련이 없습니다. 우리 업계의 많은 사람들이 원래 스스로 가르쳤다는 사실과 관련이 있습니다. 어쩌면 우리가 새로운 코더를 몇 년 동안 유지 보수 위치에 두어 잘못한 것을 알아 내야한다면 최소한 어떤 형태의 정밀도의 중요성을 이해할 것입니다.

최근에 응용 프로그램을 재 구축 할 때 리턴 코드가 다음 세 그룹 중 하나에 해당된다는 결정이 내려졌습니다.

  • 추가 정보를 통한 성공을 통해 0에서 9까지의 성공이 이루어집니다.
  • 10에서 99까지는 치명적이지 않은 (복구 가능한) 오류가되며
  • 101-255는 치명적인 오류입니다.

(100은 어떤 이유로 남겨졌다)

특정 워크 플로에서 우리의 생각은 재사용되었거나 일반 코드는 치명적 오류에 대해 일반 반환 (> 199)을 사용하여 워크 플로우에 100 가지 치명적인 오류가 발생할 수 있습니다. 메시지에서 데이터를 약간 차별화하면 파일을 찾을 수 없음과 같은 오류가 모두 동일한 코드를 사용하고 메시지와 구별 될 수 있습니다.

코드가 계약자로부터 돌아 왔을 때, 사실상 모든 단일 치명적 오류가 리턴 코드 101 일 때 놀랍지 않을 것입니다.

귀하의 질문에 대한 답변은 메시지가 너무 의미가 없다고 생각한 것으로 생각되었습니다. 원래 생성되었을 때 아무도 돌아 오지 않은 자리 표시자가 되었기 때문입니다. 결국 사람들은 메시지로 인한 문제가 아니라 문제를 해결하는 방법을 알아 냈습니다.

그 이후로, 자율 교육을받은 사람들은 예외가 무엇을 포함해야하는지에 대한 좋은 예를 결코 얻지 못했습니다. 더 많은 사용자가 메시지를 읽지 않는다는 것을 추가하십시오. 지원에 전달하려는 시도는 훨씬 적습니다 (사용 된 메시지에 의해 잘라내어 붙여 넣은 오류 메시지를 보았습니다. 많은 정보처럼 보였고 모든 것을 원하지는 않았기 때문에 무작위로 많은 정보를 제거했습니다.

그리고 더 많은 작업이 있고 플래시를 추가하지 않으면 차세대 코더가 너무 많거나 너무 많지 않으면 서 직면 할 수 있습니다.

마지막 참고 사항 : 오류 메시지에 오류 / 반환 코드가 포함되어 있으면 실행 된 모듈의 어딘가에 "조건 반환 코드 값 인 경우"와 같은 줄이 있어야하고 조건에 따라 반환 코드가 표시되어야합니다 발생했습니다. 이것은 간단한 논리적 접근 방법처럼 보이지만, 평생 동안 CODE 80241013 또는 다른 매우 고유 한 식별자에서 Windows 업그레이드가 실패했을 때 발생하는 상황을 Microsoft에 알려주도록하십시오. 슬프지 않습니까?


8
"... 거의 모든 단일 치명적 오류가 리턴 코드 101 일 때 놀랍지 않을 것입니다." 네가 옳아. 계약자가 지시를 따랐을 때 당신이 놀랐다는 것을 믿지 않을 것입니다.
Odalrick

3
chances are the users will never write it down... and you will be told "Well it said something about a violation..." 그렇기 때문에 예외 로깅 도구를 사용하여 스택 추적을 포함하는 오류 보고서를 자동으로 생성하고 서버로 전송할 수도 있습니다. 나는 한 번만 사용자가 매우 기술적이지 않았습니다. 그녀가 오류 로거로부터 메시지를 제출할 때마다 "내가 잘못한 것이 확실하지 않지만 ..."라는 오류가 몇 번이든이 오류로 인해 버그가 내 편에 있다는 것을 설명했습니다. . 그러나 나는 항상 그녀에게 오류 보고서를 받았습니다!
메이슨 휠러

3

예외에는 가능한 많은 정보가 포함되어야하거나 최소한 덜 일반적이어야한다는 데 동의합니다. 테이블을 찾을 수없는 경우 테이블 이름이 좋습니다.

그러나 예외를받은 코드에서 수행하려는 작업에 대해 더 많이 알고 있습니다. 컨트롤 외부의 라이브러리에서 문제가 발생했을 때 상황을 바로 잡기 위해 실제로 많은 일을 할 수는 없지만 문제가 발생한 상황에 대해 훨씬 더 유용한 정보를 추가 할 수 있습니다.

테이블을 찾을 수없는 경우 테이블을 찾을 수없고 코드에 문자열이 없기 때문에 찾을 수없는 테이블을 STUDENTS라고하는 경우 크게 도움이되지 않습니다.

그러나 예외를 잡아서 실행하려고하는 SQL 문으로 다시 던지면 이름 필드가 Robert '인 레코드를 삽입하려고 시도한 것이 좋습니다 .); 드롭 테이블 학생; (항상 xkcd가 있습니다!)

유익하지 않은 예외에 맞서기 위해 : 시도하려는 작업에 대한 자세한 정보로 try-catch-rethrow를 시도하십시오.

나는 이것이 질문의 이유에 대해 더 많은 대답을하기 위해 아마도 라이브러리 제작자들의 초점이 예외 메시지를 더 잘 만드는 데 초점을 두지 않은 이유는 그들이 알지 못한다고 덧붙일 것입니다. 왜 실패한 것이 시도되었는지, 그 논리는 호출 코드에 있습니다.


예를 들어 C ++ throw_with_nested에서는 많이 사용해야 합니다.
Miles Rout

3

약간 다른 답변을 제공하려면 다음을 수행하십시오.

  • 이 함수는 X를 받고 Y를 반환합니다
  • X가 유효하지 않으면 예외 Z를 처리하십시오.

최소한의 시간과 최소한의 번거 로움없이 사양 (검토 / 테스트에서 거부 될 염려가 있음)을 정확하게 전달해야한다는 압력을 가하면 완전히 준수하고 도움이되지 않는 라이브러리 예외에 대한 레시피를 갖게됩니다.


3

언어 및 구현 별 비용은 예외입니다.

예를 들어, 호출 프레임 던지기와 호출 프레임 잡기 사이의 모든 살아있는 데이터를 제거하려면 C ++ 예외가 필요하며 이는 비용이 많이 듭니다. 따라서 프로그래머는 예외를 많이 사용하고 싶지 않습니다.

Ocaml에서 예외 처리는 C만큼 빠르기 때문에 setjmp(비용은 순회 호출 프레임 수에 의존하지 않음) 개발자는 예외 예외가 아닌 매우 일반적인 경우에도이를 사용할 수 있습니다. 대조적으로, C ++ 예외는 충분히 무거 우므로 아마도 Ocaml에서와 같이 많이 사용하지 않을 것입니다.

전형적인 예는 매우 재귀 안에서 "중지"될 수있는 재귀 탐색 또는 탐색입니다 (예 : 나무에서 잎을 찾거나 통일 함수를 찾습니다). 일부 언어에서는 모든 발신자에게 해당 조건을 전파하는 것이 더 빠릅니다 (더 관용적). 다른 언어에서는 예외를 던지는 것이 더 빠릅니다.

따라서 언어 (및 언어를 사용하는 개발자의 습관)에 따라 예외는 많은 유용한 세부 정보를 전달하거나 반대로 로컬이 아닌 빠른 점프로 사용되며 매우 유용한 데이터 만 전달할 수 있습니다.


6
"예를 들어, C ++ 예외는 콜 프레임 던지기와 콜 프레임 잡기 사이의 모든 살아있는 데이터를 파괴해야하므로 비용이 많이 듭니다. 따라서 프로그래머는 예외를 많이 사용하고 싶지 않습니다." 총 쓰레기. C ++ 예외의 주요 장점은 소멸자를 결정 론적으로 호출한다는 것입니다. 그들이 뛰어 내리면 아무도 그들을 사용하지 않을 것입니다.
Miles Rout

나는 알고 있지만 C ++ 예외는 Ocaml과 같지 않으며 Ocaml에서와 같이 사용하지 않습니다.
바 실레 Starynkevitch

5
C ++에서 제어 흐름에 C ++ 예외를 사용하지 않는 이유는 주로 코드를 읽을 수없고 이해하기 어렵 기 때문입니다.
Miles Rout

-2

무엇 인덱스 값이나 필요한 범위 또는 테이블의 이름을 생각하게 입니다 예외에 대한 유용한 세부 사항?

예외는 오류 처리 메커니즘이 아닙니다. 그것들은 복구 메커니즘입니다.

예외는 예외를 처리 할 수있는 코드 수준까지 버블 링하는 것입니다. 그 수준이 어디든지, 어느 쪽이든 당신은 정보가 필요, 또는 관련이 없습니다. 필요한 정보가 있지만 즉시 액세스 할 수없는 경우 적절한 수준에서 예외를 처리하지 않은 것입니다.

추가 정보 도움이 될 있는 곳을 생각할 수있는 한 번은 응용 프로그램의 최상위 수준에서 충돌이 발생하여 오류 덤프가 발생하는 것입니다. 그러나이 정보를 액세스, 컴파일 및 저장하는 것은 예외가 아닙니다.

나는 단지 "새 예외를 던지기"를 어디에나 넣고 잘 부를 수 있다고 말하는 것은 아닙니다. 나쁜 예외를 쓰는 것이 가능합니다. 그러나 관련이없는 정보를 포함시키는 것이 적절하게 사용되는 것은 아닙니다.


나는 당신이 만들고있는 요점을 이해하고 동정하지만 누락 된 데이터베이스 테이블의 이름을 관련이없는 것으로 묘사하지 않을 것입니다. 나는 당신에게 투표권을주었습니다.
Daniel Hollinrake

1
@DanielHollinrake 예, 테이블 이름은 예제와 가장 관련이 없습니다. 내가 작업 코드에서 이러한 종류의 문제는 음울 일반적이고보고 있습니다 얼마나 엉망이 된 테이블 이름이 잘못되고있는 것이 무엇인지에 대한 단서를 제공합니다. 나는 왜 이런 것들이 예외와 관련이 없는지에 대한 예를 생각하려고 노력했다; 아마 내가 이것을 사용할 수 있습니다 ...
Odalrick

동의하지 않습니다. 예외를 처리하려면 응용 프로그램이 충돌하지 않도록 보호하기 위해 추가 세부 정보가 필요하지 않을 수 있지만 마지막으로 응용 프로그램이 작동하지 않고 문제를 해결할 수있는 이유를 알려야합니다. 단서가 없지만 예외 유형이 있으면 디버깅이 좋습니다.
t3chb0t

@ t3chb0t 이것이 예외 및 메모리 덤프의 스택 추적 및 클래스와 그 밖의 모든 것입니다. 어떻게 도움이 될 당신을 고객에 호출하고 말한다면 "컴퓨터가이 인덱스 5에 액세스하기 위해 시도하고이 아니라고 하더군요.". 그것은 당신은 또한 목록 및 유용 할 수 있습니다 목록 및 아무것도에 대한 컨텍스트를 직렬화 경우에만 도움이됩니다. 예외가 발생할 때마다 응용 프로그램의 전체 상태를 직렬화해서는 안됩니다.
Odalrick

그것은 어떤 의미가 없을 수 있습니다 고객에 대한 @Odalrick하지만 개발자로서 나는 어쩌면 또 다른 예를 들어 다음 ;-) 얻을 수있는 모든 정보를 가치 : 훨씬 쉽게 ...의이 SqlExeption가 발생하고 당신이 알고있는 모든 것을 말할 수 있도록 수리 를 어떤 연결 문자열이나 데이터베이스 또는 테이블 등이 작동하지 않는지 알고 있다면 .... 응용 프로그램이 여러 데이터베이스를 사용하는 경우 더욱 중요합니다. 자세한 스택 추적에는 pdb 파일이 응용 프로그램과 함께 제공되어야하지만 항상 가능한 것은 아닙니다. 또한 메모리 덤프는 매우 커질 수 있으며 항상 전송할 수는 없습니다.
t3chb0t
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.