HOWTO · Csharp
C#의 예외 목록
이 문서에서 발생할 수 있는 C# 예외를 살펴보겠습니다.
이 페이지의 내용
C#에서는 프로그램 실행 중 발생한 실패를 알리는 메커니즘으로 예외를 사용합니다. 구체적인 예외 유형은 무엇이 잘못되었는지 설명하며, System.Exception는 .NET 예외 계층의 공통 기본 유형입니다. 이 카탈로그는 여러 네임스페이스의 유용한 유형을 소개합니다. 전체 목록은 아니며, 사용할 수 있는 유형은 .NET 구현과 버전에 따라 달라질 수 있습니다.
C# 예외 선택 및 처리
실제 코드에서 발생할 수 있는 실패를 설명하는 유형을 선택하세요. 호출자가 제공한 값은 검증하고, 인수 문제는 ArgumentNullException, ArgumentOutOfRangeException 또는 ArgumentException으로 알리세요. 개체의 현재 상태 때문에 작업을 진행할 수 없다면 InvalidOperationException이 적절한 경우가 많습니다. 현재 상태에서만 사용할 수 없는 경우가 아니라 해당 구현이 작업 자체를 지원하지 않을 때는 NotSupportedException을 사용하세요.
프로그램이 복구하거나 유용한 맥락을 추가하거나 계층 경계에서 예외를 변환할 수 있는 지점에서 예외를 잡으세요. 가장 구체적인 유형을 먼저 잡으세요. 작업이 성공한 것처럼 계속 진행하려고 System.Exception를 무조건 잡지 마세요. 현재 계층에서 처리할 수 없는 실패는 기록하거나 전파하세요. 같은 실패를 다시 던질 때는 throw;를 사용해 원래 스택 추적을 보존하세요. 실패를 변환할 때만 throw new ...를 사용하고, 진단에 도움이 된다면 원래 예외를 내부 예외로 포함하세요.
파싱 작업을 사용하면 예외를 흐름 제어에 이용하지 않고도 사용자 입력을 사용할 수 있는지 확인할 수 있습니다. 다음 코드는 자체적으로 완결되어 있으며 이 글을 작성하는 과정에서는 실행하지 않았습니다. 제공된 입력에서 정의된 출력은 Accepted: 42입니다.
흐름 제어에 집중할 수 있도록 예제에서는 고정 문자열을 사용합니다. 실제 애플리케이션에서는 폼, 명령줄 또는 파일에서 받은 값으로 바꾸세요. TryParse 호출은 두 결과 모두에서 value를 할당합니다. 파싱된 값은 메서드가 true를 반환할 때만 의미가 있습니다. false를 반환하면 value는 기본 int 값이며, 실패 분기에서 입력을 처리합니다. 이렇게 하면 일반적인 입력 검사를 명시적으로 수행하면서 프로그램이 정상 흐름을 이어갈 수 있습니다. 문자열을 다른 정수로 바꾸고 애플리케이션에 맞게 표시 메시지를 조정할 수도 있습니다.
다음 예제를 실행하세요. 코드와 예제에서 표시되는 메시지는 바이트 단위로 그대로 유지되므로 영어로 표시됩니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
using System;
class Program
{
static void Main()
{
string input = "42";
if (int.TryParse(input, out int value))
{
Console.WriteLine($"Accepted: {value}");
}
else
{
Console.WriteLine("Enter a whole number.");
}
}
}
TryParse는 변환 실패가 예상 가능한 결과이고 호출자가 직접 처리할 수 있을 때 유용합니다. API가 예외를 던져 실패를 알린다면 문서화된 예상 예외 유형만 잡고, 관련 없는 실패는 드러나도록 두세요.
System의 예외(C#)
이 유형들은 .NET 기본 라이브러리 전반에서 찾을 수 있습니다. 아래 목록은 일부만 다룹니다. 드물게 발생하거나 특수한 런타임 동작과 관련된 유형도 있으므로, 대부분의 애플리케이션 코드는 호출하는 API가 문서화한 더 구체적인 유형을 우선해야 합니다.
AccessViolationException- 보호된 메모리에 접근하려는 시도가 감지되었습니다. 일반적으로 안전하지 않은 코드나 관리되지 않는 코드와 관련됩니다.AppDomainUnloadedException- 언로드된 애플리케이션 도메인을 사용하려고 했습니다.ApplicationException- 애플리케이션에서 정의한 실패를 위한 레거시 기본 유형입니다. 사용자 지정 유형은 일반적으로System.Exception에서 파생해야 합니다.ArgumentException- 메서드가 요구 사항을 충족하지 않는 인수를 받았습니다.ArgumentNullException- 메서드가 허용하지 않는 위치에null을 전달했습니다.ArgumentOutOfRangeException- 인수 값이 메서드에서 허용하는 범위를 벗어났습니다.ArithmeticException-DivideByZeroException과OverflowException을 포함하는 산술 관련 실패의 기본 유형입니다.ArrayTypeMismatchException- 배열에 호환되지 않는 값을 저장하려는 시도가 실패했습니다. 대개 공변 배열에서 발생합니다.BadImageFormatException- 파일을 유효한 어셈블리나 모듈로 로드할 수 없었습니다. 형식이나 아키텍처가 호환되지 않는 경우가 많습니다.CannotUnloadAppDomainException- 애플리케이션 도메인을 언로드하지 못했습니다. 주로 .NET Framework 시나리오와 관련됩니다.ContextMarshalException- 리모팅 컨텍스트 경계를 넘어 개체를 마샬링할 수 없었습니다. 이는 특수한 런타임 동작입니다.DataMisalignedException- 플랫폼이나 작업에서 충족할 수 없는 정렬 조건이 데이터 접근에 필요했습니다.DivideByZeroException- 정수 또는 10진수 나눗셈에서 제수가 0이었습니다.DllNotFoundException- 가져오기에 지정된 네이티브 라이브러리를 찾을 수 없었습니다.DuplicateWaitObjectException- 대기 작업에 같은 대기 핸들이 두 번 이상 전달되었습니다.EntryPointNotFoundException- 네이티브 라이브러리나 대상 모듈에서 요청한 진입점을 찾을 수 없었습니다.ExecutionEngineException- 레거시 런타임 실패 유형입니다. 사용이 중단되었으므로 일반적인 애플리케이션 오류에 사용하지 마세요.FieldAccessException- 대개 공개 범위나 접근 제한 때문에 코드에서 필드에 접근할 수 없었습니다.FormatException- 예상 형식과 일치하지 않는 텍스트를 파싱하는 경우처럼 값의 형식이 작업에 적합하지 않습니다.IndexOutOfRangeException- 배열 인덱스가 유효한 범위를 벗어났습니다. 이 유형은 봉인되어 있습니다.InsufficientMemoryException- 메모리 가용성 검사나 할당 관련 작업에서 요청한 메모리를 제공하지 못했습니다. 이 유형은 봉인되어 있습니다.InvalidCastException- 호환되지 않는 유형 간의 명시적 변환이 실패했습니다.InvalidOperationException- 개체의 현재 상태에서는 메서드 호출이 유효하지 않습니다.InvalidProgramException- 중간 언어나 메타데이터가 잘못되어 런타임에서 프로그램을 실행할 수 없습니다. 빌드나 도구 체인의 문제를 나타내는 경우가 많습니다.MemberAccessException- 멤버에 접근하지 못한 실패를 위한 기본 유형입니다.MethodAccessException- 대개 공개 범위나 접근 제한 때문에 코드에서 메서드에 접근할 수 없었습니다.MissingFieldException- 유형을 로드하거나 접근할 때 요청한 필드를 찾을 수 없었습니다.MissingMemberException- 요청한 멤버를 찾을 수 없었습니다.MissingMethodException- 유형을 로드하거나 접근할 때 요청한 메서드를 찾을 수 없었습니다.MulticastNotSupportedException- 대리자 유형이 지원하지 않는 방식으로 대리자를 결합하려고 했습니다.NotFiniteNumberException-NaN이나 무한대처럼 유한하지 않은 값에 관한 레거시 산술 유형입니다. 최신 코드는 대개 숫자 값을 직접 확인합니다.NotImplementedException- 멤버는 선언되었지만 구현이 아직 제공되지 않았습니다. 작업을 의도적으로 지원하지 않는다는 뜻으로 사용하지 마세요.NotSupportedException- 개체나 구현에서 요청한 작업을 지원하지 않습니다.NullReferenceException- 코드가 null 참조의 멤버를 사용하려고 했습니다. 입력 검증에 이 유형을 사용하지 말고 예기치 않은 null의 원인을 찾아 수정하세요.ObjectDisposedException- 폐기된 개체를 사용하려고 했습니다.OperationCanceledException- 작업이 취소되었습니다.TaskCanceledException은 작업에서 자주 볼 수 있는 파생 유형입니다.OutOfMemoryException- 런타임에서 필요한 메모리를 할당하지 못했습니다. 일반적으로 애플리케이션이 이 상태에서 안정적으로 복구하기는 어렵습니다.OverflowException- 검사된 산술 연산이나 변환의 결과가 대상 유형의 범위를 벗어났습니다.PlatformNotSupportedException- 현재 플랫폼에서 기능을 사용할 수 없습니다.RankException- 배열 작업에 지원되지 않는 차원 수의 배열이 전달되었습니다.StackOverflowException- 실행 스택이 소진되었습니다. 제한 없는 재귀로 발생하는 경우가 많으며 일반적으로 복구하기 어렵습니다.SystemException- 여러 시스템 정의 예외에서 사용하는 기본 유형입니다. 애플리케이션 코드는 보통 더 구체적인 파생 유형을 잡아야 합니다.TimeoutException- 작업이 허용된 시간 안에 완료되지 않았습니다. 재시도할 수 있는지는 작업에 따라 다릅니다.TypeInitializationException- 유형 초기화 프로그램이 실패했습니다. 근본 원인을 확인하려면InnerException을 살펴보세요.TypeLoadException- 예를 들어 유형 정의를 확인할 수 없어 런타임에서 유형을 로드하지 못했습니다.TypeUnloadedException- 언로드된 애플리케이션 도메인과 관련된 유형을 사용하려고 했습니다. 애플리케이션 도메인을 지원하는 런타임에 해당합니다.UnauthorizedAccessException- 운영 체제나 리소스가 요청한 접근을 거부했습니다.
System.Data의 C# 예외
이 유형들은 데이터 테이블, 제약 조건 및 관련 ADO.NET 작업과 연관됩니다. 데이터베이스 공급자는 자체 예외 유형을 제공할 수도 있으므로, 데이터베이스 실패를 진단할 때는 공급자별 세부 정보도 확인하세요.
ConstraintException- 데이터 작업이DataSet또는 관련 메모리 내 데이터 구조의 제약 조건을 위반했습니다.DataException- 데이터 관련 구성 요소에서 발생한 오류의 기본 유형입니다.DBConcurrencyException- 업데이트, 삽입 또는 삭제 작업이 예상한 행에 영향을 주지 않았습니다. 데이터를 읽은 뒤 변경된 경우가 많습니다.DeletedRowInaccessibleException- 삭제된 행에 접근하려고 했습니다.DuplicateNameException- 이미 사용 중인 이름으로 테이블이나 열을 추가하려고 했습니다.EvaluateException- 식을 평가할 수 없었습니다.InRowChangingEventException- 행 변경 이벤트 중 허용되지 않는 작업을 시도했습니다.InvalidConstraintException- 요청한 제약 조건을 만들거나 사용할 수 없었습니다.InvalidExpressionException- 데이터 식의 구문이 잘못되었거나 지정된 방식으로 평가할 수 없습니다.MissingPrimaryKeyException- 작업에 테이블의 기본 키가 필요했지만 정의되어 있지 않았습니다.NoNullAllowedException- null을 허용하지 않는 열에 null 값을 할당했습니다.OperationAbortedException- 데이터 작업이 취소되거나 중단되었습니다.ReadOnlyException- 읽기 전용 열이나 값을 변경하려고 했습니다.RowNotInTableException- 테이블에 속하지 않는 행에 대해 작업을 시도했습니다.StrongTypingException- 강력한 형식의DataSet속성에서 내부 값을 요청한 유형으로 변환할 수 없었습니다.SyntaxErrorException- 데이터 식에 구문 오류가 있습니다.TypedDataSetGeneratorException- 강력한 형식의DataSet생성기에서 오류가 발생했습니다.VersionNotFoundException- 요청한 행 버전을 사용할 수 없습니다.
System.IO의 C# 예외
파일 및 스트림 API에서는 이 유형들이 자주 보고됩니다. 다른 경로를 요청하거나 일시적인 읽기 실패를 다시 시도하는 경우처럼 애플리케이션에 복구 방법이 있는 실패만 처리하세요.
DirectoryNotFoundException- 필요한 디렉터리를 찾을 수 없었습니다.DriveNotFoundException- 필요한 드라이브나 매핑된 위치를 사용할 수 없습니다.EndOfStreamException- 끝이 정해진 스트림에서 읽기 작업이 끝을 넘어 진행되었습니다.FileLoadException- 어셈블리를 찾았지만 로드할 수 없었습니다.FileNotFoundException- 필요한 파일을 찾을 수 없었습니다.IOException- 여러 파일 및 스트림 오류를 포함하는 입출력 실패의 기본 유형입니다.PathTooLongException- 경로가 운영 체제나 사용 중인 API의 제한을 초과했습니다. 경로 제한은 플랫폼과 구성에 따라 다릅니다.
System.Net의 C# 예외
네트워크 실패는 DNS, 연결, 프로토콜 및 원격 서비스 상태에서 비롯될 수 있습니다. 구체적인 예외는 API와 .NET 버전에 따라 다릅니다. 내부 예외와 응답 세부 정보가 있으면 확인하세요.
HttpListenerException- 관련 네이티브 오류 코드와 함께HttpListener작업이 실패했습니다.ProtocolViolationException- 네트워크 작업이 API에서 기대하는 프로토콜을 위반했습니다.WebException- 웹 프로토콜을 사용하는 요청이 실패하거나 시간 초과되었거나 성공하지 못한 응답을 받았습니다. 최신 HTTP API에서는 다른 예외 유형을 사용할 수 있습니다.
System.Net.Mail의 C# 예외
SMTP 작업은 전송 계층에서 실패하거나 특정 수신자에게 실패할 수 있습니다. API의 예외 데이터에 서버 상태 정보가 포함될 수 있으므로, 메시지 내용이나 자격 증명은 로그에 남기지 마세요.
SmtpException- 일반적인 전송 또는 서버 관련 이유로 SMTP 작업이 실패했습니다.SmtpFailedRecipientException- 한 수신자에게 전송하지 못했습니다. 이 유형은SmtpException에서 파생됩니다.SmtpFailedRecipientsException- 여러 수신자에게 전송하지 못했습니다. 수신자별 세부 정보를 확인하세요.
System.Net.NetworkInformation의 C# 예외
네트워크 정보 API에서 이 유형들이 반환될 수 있습니다. 로컬 네트워크 정보를 가져오지 못했다고 해서 원격 서비스를 사용할 수 없다는 뜻은 아닙니다.
NetworkInformationException- 네트워크 정보 작업이 실패했습니다. 내부 시스템 오류 코드가 포함되는 경우가 많습니다.PingException- 내부 작업에서 오류가 발생해 ping 작업이 실패했습니다. 자세한 내용은 내부 예외를 확인하세요.
System.Resources의 C# 예외
리소스 오류는 배포 또는 현지화 구성 문제를 나타내는 경우가 많습니다. 일시적인 문제로 간주하기 전에 리소스 이름, 빌드 작업 및 위성 어셈블리 패키징을 확인하세요.
MissingManifestResourceException- 애플리케이션에 필요한 기본 리소스 매니페스트를 찾을 수 없었습니다.MissingSatelliteAssemblyException- 현지화된 리소스 집합에 필요한 위성 어셈블리를 찾을 수 없었습니다.