C#예외 처리 모범 사례
다시 이상 던지지 마세요.
나는 이 일을 한 번 또 한 번 보았다.사람들은 오류 처리 과정에서 원시 창고 추적이 신기하게 사라지는 것에 대해 곤혹스러움을 느꼈다.이것은 통상적으로 원시 이상을 던지는 것이 아니라 다시 이상을 던지는 것이다.한 가지 예를 살펴보겠습니다. 그 중에서 우리는 끼워 넣은 것이 하나 있습니다.
try/catch
try
{
try
{
// Call some other code thay may cause the SpecificException
}
catch (SpecificException specificException)
{
log.LogError(specificException, "Specific error");
}
// Call some other code
}
catch (Exception exception)
{
log.LogError(exception, "General erro");
}
이미 알고 계신 바와 같이 내부try/catch
에서 이상을 포획하고 기록하며 삼킵니다.전역 SpecificException
블록을 던지기 catch
하려면 창고에서 던져야 합니다.너는 이렇게 할 수 있다.catch (SpecificException specificException)
{
// ...
throw specificException;
}
또는 이것:catch (SpecificException specificException)
{
// ...
throw;
}
여기의 주요 차이점은 첫 번째 예시를 다시 던지는 것이다. SpecificException
이것은 원시 이상 창고 추적 리셋을 초래하고, 두 번째 예시는 원시 이상의 모든 세부 사항만 보존한다.너는 거의 항상 두 번째 예를 쓰고 싶어한다.장식 예외
나는 이런 습관이 매우 적게 사용되는 것을 보았다.모든 예외가 확장되었습니다.
Exception
사전이 있습니다.사전은 오류에 대한 추가 정보를 포함하는 데 사용할 수 있습니다.이 정보가 로그에 표시되는지 여부는 로그 프레임워크와 저장에 달려 있습니다.엠마를 위해서.ioData
항목은elmah의 데이터 옵션 카드에서 볼 수 있습니다.이오.Data
사전에 정보를 포함하려면 키/값 쌍을 추가합니다.var exception = new Exception("En error happened");
exception.Data.Add("user", Thread.CurrentPrincipal.Identity.Name);
throw exception;
이 예시에서, 나는 Data
이라는 키를 추가했는데, 이 키의 잠재적인 사용자 이름은 라인에 저장된다.외부 코드에서 발생하는 이상을 수정할 수도 있습니다.하나 추가
user
:try
{
service.SomeCall();
}
catch (Exception e)
{
e.Data.Add("user", Thread.CurrentPrincipal.Identity.Name);
throw;
}
코드 포획try/catch
방법으로 인한 모든 이상은 이상에 사용자 이름을 포함합니다.SomeCall
키워드를 throw
블록에 추가하면 원시 이상은 창고의 더 위에 던져집니다.우선 더 구체적인 이상을 포획하다
너는 네가 유사한 코드를 가지고 있다는 것을 안다.
try
{
File.WriteAllText(path, contents);
}
catch (Exception e)
{
logger.Error(e);
}
포획catch
만 하고 이를 선택한 로그 프레임워크에 기록하면 신속하게 작업을 실현하고 완성할 수 있다.대다수의 도서관이 다 있다.NET는 코드 라이브러리에 유사한 패턴이 있을 수도 있는 일련의 다른 이상을 던질 수 있습니다.여러 개의 이상을 포획하는 것은 (가장 특정한 오류부터 가장 불특정한 오류까지) 모든 종류를 어떻게 계속 처리하고 싶은지 구분하는 좋은 방법이다.다음 예제에서는 예상되는 예외와 각 예외 유형을 처리하는 방법에 대해 명확하게 설명합니다.
try
{
File.WriteAllText(path, contents);
}
catch (ArgumentException ae)
{
Message.Show("Invalid path");
}
catch (DirectoryNotFoundException dnfe)
{
Message.Show("Directory not found");
}
catch (Exception e)
{
var supportId = Guid.NewGuid();
e.Data.Add("Support id", supportId);
logger.Error(e);
Message.Show($"Please contact support with id: {supportId}");
}
포획 범위Exception
이전에 포획ArgumentException
과 DirectoryNotFoundException
를 통해 사용자에게 전용 메시지를 표시할 수 있습니다.이 장면에서 나는 이상을 기록하지 않을 것이다. 왜냐하면 사용자가 오류를 신속하게 복구할 수 있기 때문이다.Exception
의 경우 지원 id를 생성하여 오류를 기록하고 (앞에서 보듯이decorators를 사용합니다) 사용자에게 메시지를 표시합니다.위의 코드는 이상 순서를 설명하는 데 사용되지만 이러한 이상을 사용하여 흐름을 제어하는 것은 좋지 않은 방법입니다.다음 모범 사례에 대한 완벽한 설명입니다.
예외를 피하다
예외를 피하면 분명히 들릴 수 있다.그러나 많은 이상을 던지는 방법은 방어적인 프로그래밍을 통해 피할 수 있다.
가장 흔히 볼 수 있는 예외 중 하나는
Exception
이다.어떤 경우,null을 허용하기를 원하지만,null을 검사하는 것을 잊어버릴 수도 있습니다.다음은 플롯NullReferenceException
의 예입니다.Address a = null;
var city = a.City;
방문NullReferenceException
에서 이상이 발생하지만 계속 놀아주세요. a
가 매개 변수로 제공된다고 상상해 보세요.도시에서
a
값을 사용할 수 있도록 하려면 null 조건 연산자를 사용하여 이상을 피할 수 있습니다.Address a = null;
var city = a?.City;
방문null
시 추가?
를 통해 C# 자동 처리 주소가 a
인 경우.이 경우 null
변수는 값city
을 얻는다.또 다른 흔히 볼 수 있는 이상 예는 숫자나 부울 값을 분석할 때이다.다음 예제에서는 하나
null
를 내보냅니다.var i = int.Parse("invalid");
FormatException
문자열을 정수로 해석할 수 없습니다.invalid
와는 달리 try/catch
는 1000번 이상 사용할 수 있는 기발한 방법을 제공합니다.if (int.TryParse("invalid", out int i))
{
}
int
가 invalid
로 해석될 수 있다면 int
는 TryParse
로 되돌아와 해석된 값을 true
변수에 넣는다.또 다른 예외를 피했다.사용자 정의 예외 만들기
자바 프로그래머로서의 나의 세월을 회상하면 (.NET 테스트 버전으로 돌아왔을 때) 재미있다.모든 내용을 위한 사용자 정의 이상을 만들었습니다.아마도 자바에서 더 현저한 이상이 이루어졌기 때문일 것이다. 그러나 나는 이런 모델이 자바에서 자주 반복되는 것을 볼 수 없다.NET 및 C#.사용자 정의 이상을 만들면 앞에서 보듯이 특정한 이상을 더욱 잘 포착할 수 있습니다.레코더가
i
사전을 지원하는 경우, 사용자 정의 변수를 사용하여 이상을 수정할 수 있으며, 걱정하지 않아도 된다.public class MyVerySpecializedException : Exception
{
public MyVerySpecializedException() : base() {}
public MyVerySpecializedException(string message) : base(message) {}
public MyVerySpecializedException(string message, Exception inner) : base(message, inner) {}
public int Status { get; set; }
}
Data
클래스는 모든 이상 클래스가 가지고 있어야 할 세 가지 구조 함수를 실현했다.그 밖에 나는 MyVerySpecializedException
속성을 추가 데이터의 예로 추가했다.이렇게 하면 다음과 같은 코드를 작성할 수 있습니다.try
{
service.SomeCall();
}
catch (MyVerySpecializedException e) when (e.Status == 500)
{
// Do something specific for Status 500
}
catch (MyVerySpecializedException ex)
{
// Do something general
}
Status
키워드를 사용하여 when
속성의 값이 MyVerySpecializedException
일 때 포착할 수 있습니다Status
.기타 모든 상황은 총 포획량500
으로 끝납니다.로그 예외
이것은 매우 명백한 것 같다.그러나 이 모드를 사용할 때, 나는 뒤의 몇 줄에서 실패한 코드를 너무 많이 보았다.
try
{
service.SomeCall();
}
catch
{
// Ignored
}
미포획과 포획의 이상을 기록하는 것은 최소한 사용자를 위해 할 수 있는 일입니다.사용자가 지원에 연락하는 것보다 더 나쁜 것은 없습니다. 오류가 발생했고 무슨 일이 일어났는지 모릅니다.일지기록이 그걸 해줄 거야.NLog과 Serilog 등 여러 가지 훌륭한 로그 프레임워크가 있습니다.니가 ASP라면NET(Core) 웹 개발자는 elmah를 사용하여 캡처되지 않은 이상을 자동으로 기록할 수 있습니다.io 또는 기타 사용 가능한 도구 중 하나입니다.
당신의 사용자는 더 적은 오류를 좋아합니까?
엠마.io는 간단한 오류 기록과 정상적인 운행 시간 모니터링 서비스이다.그물모든 사람에 대한 지지를 통해 자신의 잘못을 다시 컨트롤하다.NET 웹 및 로그 프레임워크
➡️ Error Monitoring for .NET Web Applications ⬅️
이 문장은 처음으로 느릅나무에 나타났다.io 블로그 주소https://blog.elmah.io/csharp-exception-handling-best-practices/
Reference
이 문제에 관하여(C#예외 처리 모범 사례), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thomasardal/c-exception-handling-best-practices-4k03텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)