개요
안녕하세요. 이번 글에서는 C#의 예외 처리(exception handling)에 대해 알아보겠습니다. 프로그램 실행 중에는 0으로 나누기, 없는 파일 열기처럼 예상치 못한 오류(예외)가 발생할 수 있습니다. 이를 그냥 두면 프로그램이 멈추지만, try-catch로 감싸면 오류를 붙잡아 안전하게 처리할 수 있습니다.
try-catch 기본
오류가 날 수 있는 코드를 try 블록에 넣고, 예외가 발생하면 catch 블록이 받아서 처리합니다. 예외가 안 나면 catch는 건너뜁니다.
try
{
int a = 10, b = 0;
int result = a / b; // 0으로 나누기 → 예외 발생
Console.WriteLine(result); // 실행되지 않음
}
catch (DivideByZeroException ex)
{
Console.WriteLine("0으로 나눌 수 없습니다: " + ex.Message);
}
예외가 발생한 순간 try의 나머지는 중단되고 catch로 넘어갑니다. ex.Message로 오류 설명을 확인할 수 있습니다.
여러 예외를 구분해서 받기
catch를 여러 개 두어 예외 종류별로 다르게 처리할 수 있습니다. 구체적인 예외를 먼저, 포괄적인 Exception을 마지막에 둡니다.
try
{
// ...
}
catch (FormatException ex) // 형식 오류
{
Console.WriteLine("형식이 잘못됐습니다.");
}
catch (OverflowException ex) // 범위 초과
{
Console.WriteLine("값이 너무 큽니다.");
}
catch (Exception ex) // 그 외 모든 예외 (맨 마지막)
{
Console.WriteLine("알 수 없는 오류: " + ex.Message);
}
Exception은 모든 예외의 부모이므로, 위에 두면 다른 catch가 실행되지 않습니다. 반드시 구체적인 것 → 포괄적인 것 순서로 둡니다.
finally — 항상 실행
finally 블록은 예외가 나든 안 나든 항상 마지막에 실행됩니다. 파일 닫기, 연결 해제처럼 반드시 정리해야 하는 작업에 씁니다.
try
{
// 파일 열기 등 작업
}
catch (Exception ex)
{
Console.WriteLine("오류: " + ex.Message);
}
finally
{
Console.WriteLine("정리 작업 (항상 실행)");
// 파일 닫기 등
}
throw — 예외 던지기
직접 예외를 발생시킬 때는 throw를 씁니다. 잘못된 인자가 들어왔을 때 등에 사용합니다.
void SetAge(int age)
{
if (age < 0)
throw new ArgumentException("나이는 음수일 수 없습니다.");
// ...
}
catch 안에서 잡은 예외를 다시 위로 넘길 때는 throw;(세미콜론만)를 씁니다. throw ex;로 하면 원래 오류 위치 정보가 사라지므로, 그냥 throw;를 쓰는 것이 좋습니다.
catch (Exception ex)
{
// 로그 남기고
throw; // 원래 예외를 그대로 위로 전달 (권장)
// throw ex; // 호출 스택 정보가 사라짐 (지양)
}
정리
- 오류 가능 코드는 try, 처리는 catch에 둔다.
- catch는 구체적인 예외 → 포괄적인 Exception 순서로 여러 개 둘 수 있다.
- finally는 예외 여부와 상관없이 항상 실행 → 정리 작업에 사용.
- 직접 예외를 낼 때는 throw new …Exception().
- 잡은 예외를 다시 넘길 땐 throw; (throw ex; 는 지양).
예외를 try-catch로 감싸면 오류가 나도 프로그램이 멈추지 않고 적절히 대응할 수 있습니다. 이상으로 C# 예외 처리에 대해 간단히 알아보았습니다.