오류 처리-프로그램이 오류로 실패하거나 자동으로 무시하는 경우


20

네트워크를 통해 MIDI를 전송하는 간단한 작은 프로그램을 작성 중입니다. 프로그램에서 전송 문제 및 / 또는 예측할 수없는 기타 예외 상황이 발생한다는 것을 알고 있습니다.

예외 처리의 경우 두 가지 접근 방식이 있습니다. 프로그램을 작성해서 작성해야합니다.

  • 무언가 잘못되었을 때 뱅으로 실패 하거나
  • 데이터 무결성을 희생하면서 오류를 무시하고 계속해야합니까?

사용자는 어떤 접근법을 합리적으로 기대할 것입니까?
예외를 처리하는 더 좋은 방법이 있습니까?

또한 예외 처리에 대한 결정이 네트워크 연결을 처리하는지 여부 (예 : 문제가 발생할 것으로 예상되는 대상)에 영향을 받아야합니까?


1
@ GlenH7 Pay it forward ... :)
gnat

수정 사항을 +1하는 방법이 있습니까? ;) 아, 잠깐만 요. 물론, 할 것 :)
Arlen Beiler

2
"어떻게 접근 할 것인가?" 사용자 중 한 명에게 물어 보셨습니까? 복도 유용성 테스트는 매우 효과적 일 수 있습니다. 참조 blog.openhallway.com/?p=146
브라이언 오클리에게

나는 사용자가 없다 :)
Arlen Beiler

답변:


34

프로그램에서 발생하는 오류를 무시해서는 안됩니다. 최소한 파일이나 다른 메카니즘에 기록하여 통지해야합니다. 때때로 오류를 무시하고 문서화 하려는 상황 이있을 있습니다 ! 비어있는 catch이유를 설명하는 주석없이 빈 블록을 작성하지 마십시오 .

프로그램의 실패 여부는 상황에 따라 다릅니다. 오류를 정상적으로 처리 할 수 ​​있다면 계속하십시오. 예기치 않은 오류 인 경우 프로그램이 중단됩니다. 그것은 예외 처리의 기본입니다.


18
-1을 보증하기에는 충분하지 않지만 "never"는 강력한 단어이며, 오류를 무시하는 것이 올바른 행동 방식 인 상황이 있습니다. 예를 들어, 방송 HDTV 전송을 디코딩하는 소프트웨어. 자주 발생하는 일부 오류가 발생하면이를 무시하고 이후에 나오는 내용을 계속 디코딩하면됩니다.
whatsisname

1
@whatsisname : true, 무시 하는지 명확하게 문서화해야 합니다. 귀하의 의견을 고려하여 답변을 업데이트했습니다.
marco-fiset

1
@ marco-fiset 동의하지 않습니다. 프로그램을 다시 시작하면 문제가 해결되는 경우 전체 프로그램 충돌이 해결 방법 일뿐입니다. 항상 그런 것은 아니기 때문에 충돌이 종종 무의미하며 기본적으로 행동은 명백한 바보입니다. 지역화 된 오류로 인해 전체 작업을 일시 중단하려는 이유는 무엇입니까? 말이되지 않습니다. 대부분의 응용 프로그램은 그렇게하는데 어떤 이유로 든 프로그래머는 그 점을 잘 알고 있습니다.
MaiaVictor

@Dokkat : 요점은 잘못된 값으로 계속하지 않는 것입니다. 이는 잘못된 해결책 (쓰레기 수거, 쓰레기 수거)을 제공합니다. 충돌은 문제를 해결합니다. 사용자가 다른 입력을 제공하거나 개발자에게 프로그램을 수정하도록
강요

1
@whatsisname이 경우 "오류"에 대한 정의를 생각하고 싶을 것입니다. 수신 된 데이터의 오류는 소프트웨어 프로그램의 구조 및 실행 오류와 다릅니다.
joshin4colours

18

프로그램은 오류가 발생하기 전에 사라진 모든 것에 암묵적으로 의존하는 일련의 작업을 기반으로하기 때문에 오류를 자동으로 무시해서는 안됩니다. 3 단계에서 문제가 발생하고 4 단계로 진행하려고하면 잘못된 가정에 따라 4 단계가 시작되어 오류가 발생할 가능성이 높아집니다. (그리고 그것을 무시하면 5 단계에서 오류가 발생하고 거기에서 눈이 내리기 시작합니다.)

문제는 오류가 쌓이기 때문에 결국에는 너무 큰 오류가 발생하여 무시할 수없는 오류가 발생합니다. 오류는 사용자에게 제공되는 것으로 구성되며 무언가 잘못되었을 것입니다. 그런 다음 프로그램이 제대로 작동하지 않는다고 사용자에게 불만을 표시하고 수정해야합니다. "사용자에게 무언가 제공"부분이 28 단계에 있고 3 단계의 오류를 무시했기 때문에이 모든 혼란을 야기하는 원래 오류가 3 단계에 있었다는 것을 모른다면 문제를 디버깅하는 데 시간이 많이 걸림!

반면에, 3 단계의 오류로 인해 사용자의 얼굴이 모두 터져서 오류 SOMETHING WENT BADLY WRONG IN STEP 3!(또는 기술적으로 동등한 스택 추적)가 발생하면 결과는 동일합니다. 프로그램이 제대로 작동하지 않지만 이번에는 프로그램 을 고칠 때 어디에서 찾아야하는지 정확하게 알고 있습니다 .

편집 : 의견에 대한 응답으로, 예상치 못한 문제가 발생하고 처리 방법을 알고 있다면 다릅니다. 예를 들어 잘못된 메시지를 수신 한 경우 프로그램 오류가 아닙니다. "사용자가 잘못된 입력을 제공하여 유효성 검사에 실패했습니다." 적절한 응답은 사용자에게 잘못된 입력을 제공하고 있음을 사용자에게 알려주는 것입니다. 그런 경우에 충돌을 일으키고 스택 추적을 생성 할 필요가 없습니다.


마지막으로 성공한 위치로 돌아가거나 수신 루프의 경우 해당 메시지를 삭제하고 다음 메시지로 이동하면 어떨까요?
Arlen Beiler

@ Arlen : 그조차 나쁜 생각 일 수 있습니다. 코딩 할 때 예상하지 못한 문제가 발생하여 오류가 발생 합니다 . 이것은 모든 가정이 창 밖으로 나왔음을 의미합니다. 예를 들어 일부 데이터 구조를 수정하는 도중에 중간에 "마지막으로 알려진 올바른 위치"가 더 이상 좋지 않을 수 있습니다.
메이슨 휠러

역 직렬화를 방지하는 손상된 메시지와 같이 예상되는 경우 경우에 따라 예외를 직렬화하여 유선으로 다시 보냈습니다. 거기, 질문에 대한 편집 내용을 참조하십시오.
Arlen Beiler

@Arlen : 당신이 그것을 예상하고 오류의 영향이 무엇인지 그리고 그것이 올바르게 포함되어 있는지 확신한다면, 그것은 다릅니다. 오류를 무시하지 않고 오류를 처리하고 적절하게 응답하는 것처럼 들립니다. 예기치 않은 오류 를 무시하는 것에 대해 이야기 했습니다. 이것은 당신이 묻는 것처럼 들립니다.
메이슨 휠러

16

"폭발"과 "무시"사이에는 다른 옵션이 있습니다.

오류가 예측 가능하고 피할 수있는 경우 설계를 변경하거나 코드를 리팩터링하여 오류를 피하십시오.

오류를 예측할 수는 있지만 피할 수 없지만 오류가 발생할 때 수행 할 작업을 알고 있으면 오류를 잡아서 상황을 처리하십시오. 그러나 예외를 흐름 제어로 사용하지 않도록주의하십시오. 이 시점에서 경고를 기록하고 나중에이 상황을 피하기 위해 수행 할 수있는 조치가 있는지 사용자에게 알릴 수 있습니다.

오류가 예측 가능하고 불가피한 경우, 데이터 무결성을 보장 할 수있는 방법이 없다면 오류를 기록하고 안전한 상태로 되돌려 야합니다 (다른 사람들이 말했듯이 충돌이 발생할 수 있음).

오류가 예상 한 것이 아니라면 안전한 상태로 돌아갈 수 있다는 것을 실제로 확신 할 수 없으므로 기록하고 충돌하는 것이 가장 좋습니다.

일반적으로 로그를 기록하고 다시 던질 계획이 아니라면 아무것도 할 수없는 예외를 포착하지 마십시오. 그리고 드물게 try-catch-ignore를 피할 수없는 경우 catch 블록에 주석을 추가하여 이유를 설명하십시오.

예외 분류 및 처리에 대한 자세한 제안 은 Eric Lippert의 탁월한 예외 처리 기사 를 참조 하십시오 .


1
내 의견으로는 지금까지 가장 좋은 대답.
thursdaysgeek

6

이것들은 질문에 대한 나의 견해입니다.

좋은 출발 원리는 빨리 실패하는 것입니다. 특히 정확한 원인을 모르는 오류에 대해서는 오류 처리 코드를 작성해서는 안됩니다.

이 원칙을 적용한 후 발생한 특정 오류 조건에 대한 복구 코드를 추가 할 수 있습니다. 다시 몇 가지 "안전한 상태"를 소개 할 수도 있습니다. 프로그램 중단은 대부분 안전하지만 때로는 다른 알려진 양호한 상태로 돌아가고 싶을 수도 있습니다. 예를 들어 최신 OS가 문제를 일으키는 프로그램을 처리하는 방법이 있습니다. 전체 OS가 아닌 프로그램 만 종료합니다.

점점 더 구체적인 오류 조건을 신속하고 천천히 처리함으로써 데이터 무결성을 훼손하지 않고보다 안정적인 프로그램으로 꾸준히 이동할 수 있습니다.

오류를 삼키는 것, 즉 정확한 원인을 모르고 특정 복구 전략이없는 오류를 계획하려고하면 프로그램에서 오류가 발생하고 코드를 우회하는 것만 증가합니다. 이전 데이터가 올바르게 처리되었다는 것을 신뢰할 수 없으므로 데이터가 잘못되었거나 누락되었는지에 대한 스프레드 검사가 시작됩니다. 사이클로 매틱의 복잡성은 손에서 나올 것이고 커다란 진흙 공으로 끝날 것입니다.

실패 사례를 알고 있는지 여부는 덜 중요합니다. 그러나 예를 들어 특정 양의 오류 상태를 알고있는 네트워크 연결을 처리하는 경우 복구 코드를 추가 할 때까지 오류 처리 추가를 연기하십시오. 이것은 위에서 설명한 원칙과 일치합니다.


6

오류를 자동으로 무시 해서는 안됩니다 . 특히 데이터 무결성을 희생 하지는 않습니다 .

프로그램이 무언가를 시도하고 있습니다. 그것이 실패하면, 당신은 사실에 직면하고 그것에 대해 뭔가 를해야합니다. 그것이 무엇인지는 많은 것들에 달려 있습니다.

결국 사용자는 프로그램이 무언가를하도록 요청했고 프로그램은 성공하지 못했다고 알려야합니다. 그것을하는 방법에는 여러 가지가 있습니다. 즉시 중지 될 수도 있고 이미 완료된 단계를 롤백 할 수도 있고, 다른 한편으로는 수행 할 수있는 모든 단계를 계속하고 완료 할 수도 있으며 사용자에게 이러한 단계가 성공했으며 다른 단계는 실패했다고 알려줄 수도 있습니다.

선택하는 방법은 단계가 얼마나 밀접하게 관련되어 있는지와 향후 모든 단계에서 오류가 다시 발생할 가능성에 따라 결정되며, 이는 정확한 오류에 따라 달라질 수 있습니다. 강력한 데이터 무결성이 필요한 경우 일관성있는 마지막 상태로 롤백해야합니다. 많은 파일을 복사하는 경우 일부 파일을 건너 뛰고 파일을 복사 할 수 없다고 사용자에게 말하면됩니다. 자동으로 파일을 건너 뛰지 말고 사용자에게 아무 것도 말하지 마십시오.

광고 수정의 유일한 차이점은 네트워크에 다시 시도해도 다시 발생하지 않는 일시적인 오류가있을 수 있으므로 포기하고 사용자에게 작동하지 않았다고 알리기 전에 몇 번의 재 시도를 고려해야한다는 것입니다.


첫 줄 끝에 물음표를 붙이려 고 하셨나요?
CVn

@ MichaelKjörling : 아니오. 복사-붙여 넣기 오류 (질문에서 공식을 복사하고 실수로 물음표를 포함).
Jan Hudec

4

오류를 무시하는 것이 옳은 경우에는 한 가지 부류가 있습니다. 상황에 대해 수행 할 수있는 작업이없고 결과가없는 것보다 가난하고 잘못된 결과가 더 나은 경우.

디스플레이 목적으로 HDMI 스트림을 디코딩하는 경우가 그러한 경우이다. 스트림이 나쁘면 나쁘고 소리를 지르면 마술처럼 고치지 않습니다. 표시 할 수있는 작업을 수행하고 시청자가 허용 가능한지 여부를 결정하게합니다.


1

프로그램이 문제가 발생할 때마다 자동으로 무시하거나 혼란을 유발해서는 안된다고 생각합니다.

회사를 위해 작성한 내부 소프트웨어로 수행하는 작업 ...

그것은 오류에 달려 있으며 MySQL에 데이터를 입력하는 중요한 기능이라면 사용자에게 실패했음을 알려야합니다. 오류 처리기는 많은 정보를 수집하고 사용자가 실수를 직접 수정하여 데이터를 저장할 수있는 방법에 대한 아이디어를 사용자에게 제공해야합니다. 또한 저장하려는 위치에 정보를 자동으로 전송하는 방법을 제공하여 더 나빠질 경우 버그를 수정 한 후 직접 입력 할 수 있습니다.

중요한 기능이 아닌 오류가 발생하여 달성하려는 최종 결과에 영향을 미치지 않는 경우 오류 메시지를 표시하지 않지만 버그 추적 소프트웨어에 자동으로 삽입하는 전자 메일을 보내도록합니다. 또는 사용자가 아닌 경우에도 오류를 인식 할 수 있도록 회사의 모든 프로그래머에게 경고하는 전자 메일 그룹입니다. 이를 통해 우리는 백엔드를 고칠 수 있지만 프론트 엔드에서는 아무도 무슨 일이 일어나고 있는지 알 수 없습니다.

내가 피하려고하는 가장 큰 것 중 하나는 오류 후 프로그램이 중단되어 복구 할 수 없다는 것입니다. 항상 사용자에게 응용 프로그램을 닫지 않고 계속할 수있는 옵션을 제공하려고합니다.

아무도 버그에 대해 모른다면 믿어지지 않을 것입니다. 또한 오류가 발견되면 응용 프로그램이 계속 작동 할 수 있도록하는 오류 처리를 확고히 믿습니다.

오류가 네트워크와 관련된 경우-먼저 오류를 피하기 위해 함수를 실행하기 전에 함수가 간단한 네트워크 통신 테스트를 수행하지 않는 이유는 무엇입니까? 그런 다음 연결을 사용할 수 없음을 사용자에게 알리면 인터넷 등을 확인하고 다시 시도하십시오.


1
나는 완전히 이해하지 못하고 자세한 정보를 반환하는 유용한 오류 처리를 제공 할 수없는 오류를 제한하기 위해 중요한 기능을 실행하기 전에 개인적으로 많은 검증을 수행합니다. 100 % 작동하지 않지만 몇 시간 동안 잃어버린 버그가 발생한 마지막 시간을 기억할 수 없습니다.
Jeff

1

내 자신의 전략은 코딩 오류 (버그)와 런타임 오류구별 하고 가능한 한 코딩 오류를 만들기 어렵게 만드는 것입니다.

버그 는 가능한 빨리 수정해야하므로 계약 별 설계 방식이 적합합니다. C ++에서는 가능한 한 빨리 버그를 감지하고 디버거를 연결하고 버그를 쉽게 수정할 수 있도록 함수 맨 위에 어설 션이있는 모든 전제 조건 (입력)을 확인하고 싶습니다. 개발자 나 테스터가 대신 프로그램을 계속 실행하려고하면 데이터 무결성 손실이 문제가됩니다.

그리고 먼저 버그를 방지 할 수있는 방법을 찾으십시오. const-correctness를 엄격하게 유지하고 보유 할 데이터에 적합한 데이터 유형을 선택하는 것은 버그 생성을 어렵게하는 두 가지 방법입니다. Fail-Fast 는 또한 복구 방법이 필요한 안전 핵심 코드 외부에서도 우수합니다.

네트워크 또는 직렬 통신 오류 또는 파일 누락 또는 손상과 같이 버그가없는 코드로 발생할 수있는 런타임 오류의 경우 :

  1. 오류를 기록하십시오.
  2. (선택 사항) 조작을 자동으로 다시 시도하거나 복구하려고합니다.
  3. 작업이 계속 실패하거나 복구 할 수없는 경우 사용자에게 오류를 시각적으로보고하십시오. 그런 다음 위와 같이 사용자가 수행 할 작업을 결정할 수 있습니다. 사전에 경고하지 않는 한 데이터 무결성 손실이 사용자에게 놀라운 것이기 때문에 Least Astonishment원칙을 기억하십시오 .

0

실패는 프로그램의 전체 상태가 불안정하다고 생각할만한 이유가 있고 지금부터 실행할 경우 나쁜 일이 발생할 수 있습니다. "무시" "다른 사람이 지적했듯이, 어딘가에 기록하거나 사용자에게 오류 메시지를 표시 한 다음 계속"은 현재 작업을 수행 할 수 없지만 프로그램은 계속 달려.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.