문제

데이터 액세스 계층 깊은 곳이나 그보다 더 높은 곳에서 발생하는 오류(예: ADO.net 작업 내에서)는 최종 사용자에게 거의 의미가 없습니다.단순히 이러한 오류를 UI에 표시하고 표시하는 것은 일반적으로 최종 사용자에게 좌절감을 주는 것 외에는 아무것도 얻지 못합니다.

나는 최근에 오류를 포착하고 적어도 최종 사용자가 무엇이 실패했는지 이해할 수 있도록 사용자에게 친숙한 텍스트를 추가하는 것과 같은 오류 보고를 위한 기본 기술을 사용했습니다.

이를 위해 각 특정 함수(예: 데이터 액세스 계층의 가져오기 함수) 내에서 예외를 포착한 다음 실패하고 원인이 될 수 있는 함수에 대한 사용자 친화적인 텍스트로 새 오류를 발생시킨 다음 원본을 삽입합니다. 새로운 예외의 "내부 예외"로서 새로운 예외의 예외.

그런 다음 필요한 경우 각 계층에서 발생할 수 있으며 하위 수준 기능의 각 소비자는 오류 메시지에 자신의 컨텍스트를 추가하므로 UI에 도달하는 내용은 점점 더 사용자 친화적인 오류 메시지가 됩니다.

오류가 UI에 도달하면(필요한 경우) 먼저 사용자에게 어떤 작업이 실패했는지 알려주는 오류 메시지를 표시하기 위해 중첩된 예외를 반복할 수 있지만 실제로 무엇이 잘못되었는지에 대한 약간의 기술 정보도 제공합니다.

예를 들어

"요청한 고객 이름 목록은 표시 될 수 없습니다."

"데이터베이스의 오류로 인해 요청한 고객 목록을 얻는 것이 실패했습니다."

"고객 목록을 검색 할 때 데이터베이스에 연결하는 오류가있었습니다."

"사용자 xx의 로그인에 실패했습니다."

내 질문은 이것입니다:이것이 엄청나게 비효율적입니까(모든 중첩된 예외)?나는 그것이 모범 사례가 아니라고 생각합니다. 그렇다면 동일한 것을 달성하기 위해 무엇을 해야 합니까? 아니면 실제로 더 나은 것을 달성하기 위해 노력해야 합니까?

도움이 되었습니까?

해결책

조금 끔찍할 뿐입니다.

최종 사용자에게 오류를 표시하는 경우 사용자는 이에 대해 조치를 취할 수 있어야 합니다."요청한 고객 이름 목록을 표시 할 수 없습니다." 사례, 사용자는 단지 "그래서 뭐야?"라고 생각할 것입니다. 이 모든 경우에 "나쁜 일이 발생한 것"메시지 만 표시하십시오.이러한 예외를 포착할 필요조차 없습니다. 문제가 발생하면 일부 전역 메소드(예: application_error)가 이를 처리하고 일반 메시지를 표시하도록 하십시오.귀하 또는 귀하의 사용자가 오류에 대해 조치를 취할 수 있는 경우 이를 포착하여 조치를 취하거나 사용자에게 알립니다.

그러나 처리하지 못한 모든 오류를 기록하고 싶을 것입니다.

그런데 발생한 오류에 대한 정보를 표시하면 보안 취약점이 발생할 수 있습니다.공격자가 시스템에 대해 덜 알수록 해킹 방법을 찾을 가능성도 줄어듭니다("SQL 문의 구문 오류:* 사용자 이름이 'a'인 사용자로부터 선택;drp 데이터베이스;--'..." 예상:'drp' 대신 'drop'입니다.더 이상 이런 사이트를 만들지 않습니다.)

다른 팁

새로운 예외를 발생시키는 것은 기술적으로 비용이 많이 들지만, "비용이 많이 든다"는 것은 상대적이기 때문에 그것에 대해 큰 논쟁을 벌이지는 않을 것입니다. 1분에 이러한 예외를 100개 발생시키는 경우에는 비용이 발생하지 않을 가능성이 높습니다.초당 1000개의 예외를 발생시키는 경우 성능 저하가 발생할 수 있습니다(따라서 여기서는 실제로 논의할 가치가 없습니다. 성능이 귀하의 선택입니다).

왜 이런 접근 방식을 사용하는지 물어봐야 할 것 같습니다.에 의미 있는 예외 정보를 추가할 수 있다는 것이 정말 사실인가요? 모든 예외가 발생할 수 있는 수준, 그렇다면 정보는 다음과 같습니다.

  • 당신이 실제로 뭔가 원하다 사용자와 공유하시겠습니까?
  • 사용자가 해석하고 이해할 수 있는 것 사용?
  • 나중에 저수준 구성 요소를 재사용하는 것을 방해하지 않는 방식으로 작성되었으며, 작성 당시에는 그 유용성이 알려지지 않았을 수 있습니까?

귀하의 예에서 인공 스택은 사용자에게 데이터베이스 인증에 문제가 있음을 알리는 것으로 시작되기 때문에 사용자와 정보를 공유하는 것에 대해 질문합니다.잠재적인 해커에게 이는 해당 작업이 수행 중인 작업에 대한 정보를 노출하는 좋은 정보입니다.

전체 사용자 정의 예외 스택을 돌려주는 것에 관해서는 이것이 대부분의 (정직한) 사용자에게 유용할 것이라고 생각하지 않습니다.예를 들어, 고객 이름 목록을 얻는 데 문제가 있는 경우 데이터베이스 인증에 문제가 있음을 아는 것이 (사용자로서) 도움이 될까요?통합 인증을 사용하지 않고, 각 사용자가 계정을 가지고 있고, 계정에 권한이 부족한 이유를 알아보기 위해 시스템 관리자에게 문의할 수 있는 기능이 없다면 아마도 그렇지 않을 것입니다.

먼저 발생한 프레임워크 예외와 사용자에게 제공하려는 예외 메시지 사이에 실제로 의미론적 차이가 있는지 결정하는 것부터 시작하겠습니다.있는 경우 가장 낮은 수준(예제에서는 '로그인 실패')에서 사용자 지정 예외를 사용하세요.예외가 실제로 표시될 때까지 이어지는 단계에서는 실제로 사용자 지정 예외가 필요하지 않습니다.관심 있는 예외가 이미 생성되었습니다(로그인 실패). 호출 스택의 모든 수준에서 해당 메시지를 계속 래핑하는 것은 호출 스택을 사용자에게 노출시키는 것 외에는 실제 목적을 제공하지 않습니다."중간" 단계의 경우 try/catch 블록이 있다고 가정하면 간단한 'log and throw' 전략이 제대로 작동합니다.

하지만 실제로 이 전략에는 또 다른 잠재적인 결함이 있습니다.이는 구현된 사용자 정의 예외 표준을 유지 관리할 책임을 개발자에게 강요합니다.낮은 수준 유형을 작성할 때 호출 계층 구조의 모든 순열을 알 수 없기 때문에(해당 "클라이언트"가 아직 작성되지 않았을 수도 있음) 모든 개발자, 심지어 한 명의 개발자라도 래핑 및 사용자 정의를 기억할 가능성은 거의 없습니다. 모든 코드 블록의 모든 오류 조건.

상향식으로 작업하는 대신 일반적으로 프로세스 후반에 던져진 예외를 표시하는 것에 대해 걱정합니다(예:가능한 한 호출 스택의 "상단"에 가깝게).일반적으로 나는 내 응용 프로그램의 낮은 수준에서 발생한 예외의 메시지를 대체하려고 시도하지 않습니다. 특히 호출이 깊어질수록 낮은 수준 멤버의 사용이 점점 더 추상화되는 경향이 있기 때문입니다.저는 비즈니스 계층 이하에서 예외를 포착하고 기록한 다음 프레젠테이션 계층에서 이를 이해하기 쉬운 방식으로 표시하는 경향이 있습니다.

다음은 예외 처리 모범 사례에 대한 몇 가지 유용한 기사입니다.

http://www.codeproject.com/KB/architecture/Exceptionbestpractices.aspx

http://aspalliance.com/1119

이런, 말이 너무 길어졌네요...미리 사과드립니다.

예, 예외는 비용이 많이 들기 때문에 더 유용한 예외를 포착하고 다시 발생시키거나 발생시키는 데 비용이 듭니다.

하지만 잠깐만요!사용 중인 프레임워크 코드나 라이브러리에서 예외가 발생하면 문제가 이미 해결된 것입니다.예외 발생 후 오류 메시지가 얼마나 빨리 전파되는지에 대한 비기능적 요구 사항이 있습니까?나는 그것을 의심한다.정말 큰일인가요?예상치 못한 '예외적인' 일이 일어났습니다.가장 중요한 것은 사용자에게 합리적이고 유용한 정보를 제공하는 것입니다.

나는 당신이 하고 있는 일이 올바른 방향으로 가고 있다고 생각합니다.

물론 엄청나게 비효율적이다.하지만 최종 사용자에게 보여줄 만큼 중요한 예외가 발생하는 시점에서는 이에 대해 신경 쓰지 않아도 됩니다.

제가 일하는 곳에서는 예외를 잡아야 하는 이유가 몇 가지 밖에 없습니다.우리는 그럴 때만 한다...

  1. 이에 대해 뭔가 조치를 취할 수 있습니다. 예를 들어 이런 일이 가끔 발생할 수 있다는 것을 알고 있으며 발생하는 대로 코드에서 수정할 수 있습니다(매우 드물지만).

  2. 우리는 그것이 어디서 발생하는지 알고 싶습니다(그런 다음 예외를 다시 발생시킵니다).

  3. 우리는 응용 프로그램 예외에서 파생된 새로운 예외로 원래 예외를 래핑하고 여기에 친숙한 메시지를 추가한 다음 해당 지점에서 변경되지 않고 버블링되도록 하는 친숙한 메시지를 추가하려고 합니다.

귀하의 예에서는 아마도 "로그온 오류가 발생했을 것"을 표시했을 것입니다. ANBD는 실제 오류를 기록하고 사용자가 원하는 경우 예외를 드릴 수있는 이유를 제공하는 동안 그에 남겨 둡니다.(아마도 오류 양식의 버튼일 것입니다).

  1. 우리는 예외를 완전히 억제하고 계속 진행하고 싶습니다.말할 필요도 없이 우리는 예상되는 예외 유형에 대해서만 그리고 예외를 생성하는 조건을 감지할 수 있는 다른 방법이 없는 경우에만 이 작업을 수행합니다.

일반적으로 예외를 처리할 때 성능과 효율성은 걱정거리가 가장 적습니다.사용자가 문제를 복구하는 데 도움이 되는 조치를 취하는 것에 대해 더 걱정해야 합니다.특정 레코드를 데이터베이스에 쓰는 데 문제가 있는 경우 변경 사항을 롤백하거나 최소한 행 정보를 덤프하여 사용자가 정보를 잃지 않도록 하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top