이 메시지는 다른 개발자를위한 것입니다
이러한 메시지는 개발자 가 응용 프로그램을 디버깅하는 데 도움 이되도록 읽습니다 . 두 가지 형태가 있습니다.
액티브 디버깅. 실제로 코드를 작성하고 어떤 일이 발생하는지 파악하는 동안 디버거를 실행하고 있습니다. 이와 관련하여 도움이되는 예외는 무엇이 잘못되었는지 쉽게 이해하도록하거나 결국 대안을 제안함으로써 도움이 될 것입니다 (선택 사항 임에도 불구하고).
패시브 디버깅. 코드가 프로덕션 환경에서 실행되고 실패합니다. 예외는 기록되지만 메시지와 스택 추적 만받습니다. 이와 관련하여 유용한 예외 메시지는 버그를 신속하게 지역화하는 데 도움이됩니다.
이러한 메시지는 종종 기록되기 때문에 민감한 정보 (예 : 앱을 디버깅하는 데 유용한 경우에도 개인 키 또는 비밀번호)를 포함해서는 안됩니다.
예를 들어, IOSecurityException
파일을 쓸 때 발생하는 예외 유형은 문제에 대해 명확하지 않습니다. 파일에 액세스 할 수있는 권한이 없기 때문입니까? 아니면 읽을 수는 있지만 쓸 수는 없습니까? 아니면 파일이 존재하지 않고 파일을 만들 수있는 권한이 없습니까? 또는 잠겨있을 수 있습니다 (이 경우에는 예외 유형이 다르지만 실제로 유형은 때로는 암호가 될 수 있습니다). 아니면 코드 액세스 보안으로 인해 I / O 작업을 수행하지 못할 수 있습니까?
대신 :
IOSecurityException : 파일을 찾았지만 해당 내용을 읽을 수있는 권한이 거부되었습니다.
훨씬 더 명시 적입니다. 여기서는 디렉토리에 대한 권한이 올바르게 설정되었음을 알지만 (그렇지 않으면 파일이 존재한다는 것을 알 수는 없지만) 파일 수준의 권한에 문제가 있습니다.
또한 아직 예외 유형이 아닌 추가 정보를 제공 할 수없는 경우 메시지를 비워 둘 수 있습니다. DivisionByZeroException
메시지가 중복되는 좋은 예입니다. 반면에 대부분의 언어에서 메시지를 지정하지 않고 예외를 발생시킬 수 있다는 사실은 다른 이유로 인해 수행됩니다. 기본 메시지가 이미 사용 가능하거나 필요할 경우 나중에 생성되기 때문입니다. 메시지는 "OOPly" 말하기 와 같은 예외 유형에 포함 됩니다.
기술적 인 (종종 성능) 이유로 인해 일부 메시지는 원래보다 훨씬 더 암호화되어 있습니다. .NET NullReferenceException
:
객체 참조가 객체의 인스턴스로 설정되지 않았습니다.
도움이되지 않는 메시지의 훌륭한 예입니다. 유용한 메시지는 다음과 같습니다.
product
에서 호출 될 때 객체 참조 가 객체의 인스턴스로 설정되지 않았습니다 product.Price
.
이러한 메시지는 최종 사용자를위한 것이 아닙니다!
최종 사용자에게는 예외 메시지가 표시되지 않습니다. 못. 일부 개발자는 결국 이러한 메시지를 사용자에게 보여 주지만 사용자 경험이 나쁘고 좌절됩니다. 다음과 같은 메시지 :
객체 참조가 객체의 인스턴스로 설정되지 않았습니다.
최종 사용자에게는 전혀 의미가 없으며 모든 비용을 피해야합니다.
최악의 시나리오는 전역 try / catch를 사용하여 예외를 사용자에게 던지고 앱을 종료하는 것입니다. 사용자를 걱정하는 응용 프로그램 :
우선 예외를 처리합니다. 대부분은 사용자를 방해하지 않고 처리 할 수 있습니다. 네트워크가 다운 되었습니까? 몇 초 기다렸다가 다시 시도해보십시오.
사용자가 응용 프로그램을 예외적 인 사례로 이끌지 못하게합니다. 사용자에게 두 개의 숫자를 입력하고 첫 번째 숫자를 두 번째 숫자로 나누도록 요청하는 경우 몇 초 후에 사용자를 비난 하기 위해 두 번째 경우에 0을 입력하게하는 이유는 무엇입니까? 텍스트 상자를 빨간색으로 강조 표시하고 (숫자가 0이 아니어야한다는 유용한 도구 설명과 함께) 필드가 빨간색으로 유지 될 때까지 유효성 검사 버튼을 비활성화하는 것은 어떻습니까?
사용자에게 오류가 아닌 형태로 작업을 수행하도록 초대합니다. 파일에 액세스 할 수있는 권한이 충분하지 않습니까? 사용자에게 관리 권한을 부여하거나 다른 파일을 선택하도록 요청하지 않는 이유는 무엇입니까?
아무것도 작동하지 않으면 사용자의 불만을 줄이기 위해 특별히 작성된 유용하고 친숙한 오류를 보여 주어 사용자가 잘못 된 것을 이해하고 결국 문제를 해결하도록 도와주고 향후 해당 오류를 방지 할 수 있도록 도와줍니다 (해당되는 경우).
귀하의 질문에 예외적으로 두 가지 메시지, 즉 개발자를위한 기술적 인 메시지와 최종 사용자를위한 메시지를 두도록 제안했습니다. 이는 사소한 경우에 유효한 제안이지만 대부분의 예외는 사용자에게 의미있는 메시지를 생성 할 수없는 수준에서 생성됩니다. 가지고 DivisionByZeroException
우리가 일어나는 예외를 방지 할 수 있고 그것을 자신을 처리 할 수없는 것을 상상한다. 부서가 발생하면 프레임 워크 (예외를 발생시키는 비즈니스 코드가 아닌 프레임 워크이므로)는 사용자에게 유용한 메시지가 무엇인지 알고 있습니까? 절대적으로하지:
0으로 나누기가 발생했습니다. [승인]
대신 예외를 던지고 비즈니스 컨텍스트를 알고 더 높은 수준에서 예외를 잡아서 최종 사용자를 실제로 돕기 위해 조치를 취할 수 있습니다.
D13 필드는 E6 필드의 값과 동일한 값을 가질 수 없습니다. 해당 값의 빼기가 제수로 사용되기 때문입니다. [승인]
또는 아마도 :
ATP 서비스에서보고 한 값이 로컬 데이터와 일치하지 않습니다. 로컬 데이터가 동기화되지 않았기 때문일 수 있습니다. 운송 정보를 동기화하고 다시 시도 하시겠습니까? [예 아니오]
이 메시지는 파싱 용이 아닙니다
예외 메시지는 프로그래밍 방식 으로 구문 분석 되거나 사용될 것으로 예상되지 않습니다 . 발신자가 추가 정보를 필요로한다고 생각되면 예외와 함께 메시지와 함께 추가하십시오. 메시지는 예고없이 변경 될 수 있으므로 중요합니다. 유형은 인터페이스의 일부이지만 메시지는 그렇지 않습니다. 예외 처리에 의존하지 마십시오.
예외 메시지를 상상해보십시오.
500 ms 동안 기다린 후 캐싱 서버 연결 시간이 초과되었습니다. 시간 초과를 늘리거나 성능 모니터링을 확인하여 서버 성능 저하를 식별하십시오. 캐싱 서버의 평균 대기 시간은 6ms입니다. 지난 달 4ms 지난 주와 377ms 동안 마지막 시간 동안.
"500", "6", "4"및 "377"값을 추출하려고합니다. 구문 분석을 수행하는 데 사용할 접근 방식에 대해 약간 생각한 다음 읽기만 계속하십시오.
당신은 아이디어가 있습니까? 큰.
이제 원래 개발자가 오타를 발견했습니다.
Connecting to the caching sever timed out after waiting [...]
해야한다:
↓
Connecting to the caching server timed out after waiting [...]
또한 개발자는 월 / 주 / 1 시간이 특별히 관련이 없다고 생각하므로 추가 변경도 수행합니다.
캐싱 서버의 평균 대기 시간은 6ms입니다. 지난 달 5ms. 지난 24 시간 동안 377ms 마지막 한 시간 동안.
파싱은 어떻게됩니까?
구문 분석 대신 예외 속성을 사용할 수 있습니다 (데이터를 직렬화하는 즉시 원하는 것을 포함 할 수 있음).
{
message: "Connecting to the caching [...]",
properties: {
"timeout": 500,
"statistics": [
{ "timespan": 1, "unit": "month", "average-timeout": 6 },
{ "timespan": 7, "unit": "day", "average-timeout": 4 },
{ "timespan": 1, "unit": "hour", "average-timeout": 377 },
]
}
}
이 데이터를 지금 사용하는 것이 얼마나 쉬운가요?
경우에 따라 (예 : .NET 내에서) 메시지가 사용자 언어로 번역 될 수도 있습니다 (IMHO, 개발자가 영어로 읽을 수 있기 때문에 해당 메시지를 번역하는 것은 절대적으로 잘못되었습니다). 그러한 메시지를 파싱하는 것은 거의 불가능합니다.