
Dart의 예외 처리 (try - catch - finally)
Dart에서는 예외(Exception)가 발생할 수 있는 코드를 안전하게 실행하기 위해 try-catch-finally 문을 제공합니다.
예외 처리는 프로그램의 갑작스러운 중단을 방지하고, 오류를 처리하여 정상적으로 동작하도록 돕습니다.
1. 예외(Exception)란?
Dart에서 예외는 실행 중에 발생하는 예기치 않은 오류를 의미합니다.
예를 들어, 0으로 나누기, 없는 리스트 요소 접근, 네트워크 연결 오류 등이 예외에 해당합니다.
예외가 발생하면 프로그램이 중단되므로 이를 방지해야 합니다.
void main() {
int a = 10, b = 0;
print(a ~/ b); // 오류 발생 (정수를 0으로 나눌 수 없음)
}
- 위 코드는 IntegerDivisionByZeroException 예외를 발생시키며 프로그램이 중단됩니다.
2. try - catch 문법
2.1 기본 예외 처리
예외가 발생할 가능성이 있는 코드를 try 블록에 작성하고, catch 블록에서 오류를 처리합니다.
void main() {
try {
int a = 10, b = 0;
print(a ~/ b); // 예외 발생
} catch (e) {
print("예외 발생: $e");
}
}
예외 발생: IntegerDivisionByZeroException
2.2 예외 정보 출력 (catch(e, s))
예외가 발생한 스택 추적(Stack Trace) 정보를 확인하려면 catch(e, s)를 사용합니다.
void main() {
try {
List<int> numbers = [1, 2, 3];
print(numbers[5]); // 오류 발생 (인덱스 초과)
} catch (e, s) {
print("예외 발생: $e");
print("스택 추적: $s");
}
}
예외 발생: RangeError (index): Invalid value: Not in inclusive range 0..2: 5
스택 추적: #0 main (file.dart:5:16)
...
- catch (e, s)에서 s는 에러 발생 위치와 원인을 분석할 때 유용합니다.
3. on 키워드로 특정 예외 처리
모든 예외를 catch에서 처리할 수도 있지만, 특정 예외만 따로 처리할 수도 있습니다.
void main() {
try {
int a = 10, b = 0;
print(a ~/ b); // 정수 나누기 예외 발생
} on IntegerDivisionByZeroException {
print("0으로 나눌 수 없습니다.");
} catch (e) {
print("알 수 없는 오류: $e");
}
}
0으로 나눌 수 없습니다.
- on 키워드를 사용하면 특정 예외를 별도로 처리할 수 있습니다.
4. finally 블록
finally 블록은 예외 발생 여부와 관계없이 항상 실행됩니다.
주로 파일 닫기, 데이터베이스 연결 해제, 정리 작업 등에 사용됩니다.
void main() {
try {
int a = 10, b = 0;
print(a ~/ b);
} catch (e) {
print("예외 발생: $e");
} finally {
print("항상 실행되는 finally 블록");
}
}
예외 발생: IntegerDivisionByZeroException
항상 실행되는 finally 블록
- finally 블록은 오류 발생과 관계없이 실행되므로, 정리 작업을 수행할 때 유용합니다.
5. 예외 던지기 (throw)
Dart에서는 throw를 사용하여 직접 예외를 발생시킬 수 있습니다.
void checkAge(int age) {
if (age < 18) {
throw Exception("미성년자는 접근할 수 없습니다.");
} else {
print("접속 허용");
}
}
void main() {
try {
checkAge(15);
} catch (e) {
print("예외 발생: $e");
}
}
예외 발생: Exception: 미성년자는 접근할 수 없습니다.
- throw를 사용하면 개발자가 직접 예외를 정의하고 발생시킬 수 있습니다.
6. 사용자 정의 예외 (Custom Exception)
Dart에서는 사용자 정의 예외 클래스를 만들어 특정 오류를 구분할 수 있습니다.
class AgeException implements Exception {
String errorMessage() => "미성년자는 접근할 수 없습니다.";
}
void checkAge(int age) {
if (age < 18) {
throw AgeException();
} else {
print("접속 허용");
}
}
void main() {
try {
checkAge(15);
} catch (e) {
print("예외 발생: ${e is AgeException ? e.errorMessage() : e}");
}
}
예외 발생: 미성년자는 접근할 수 없습니다.
- implements Exception을 사용하여 사용자 정의 예외 클래스를 만들 수 있습니다.
7. rethrow 키워드
rethrow 키워드는 현재 catch 블록에서 예외를 다시 던지는 역할을 합니다.
이는 예외를 일부 처리한 후, 상위 호출 스택으로 전달해야 할 때 유용합니다.
void riskyFunction() {
try {
throw Exception("예기치 않은 오류!");
} catch (e) {
print("예외 처리 중... 예외를 다시 던집니다.");
rethrow;
}
}
void main() {
try {
riskyFunction();
} catch (e) {
print("메인 함수에서 최종 예외 처리: $e");
}
}
예외 처리 중... 예외를 다시 던집니다.
메인 함수에서 최종 예외 처리: Exception: 예기치 않은 오류!
- rethrow는 현재 catch 블록에서 예외를 추가적으로 처리한 후, 다시 상위에서 처리하도록 전달하는 역할을 합니다.
8. 예외 처리 활용 예제
8.1 파일 읽기 시 예외 처리 (Dart I/O)
import 'dart:io';
void readFile(String filePath) {
try {
File file = File(filePath);
String contents = file.readAsStringSync();
print(contents);
} on FileSystemException catch (e) {
print("파일을 찾을 수 없습니다: ${e.message}");
}
}
void main() {
readFile("non_existent_file.txt");
}
- 파일이 존재하지 않을 경우 FileSystemException을 처리합니다.
키워드 | 설명 |
try | 예외가 발생할 가능성이 있는 코드 블록 |
catch (e) | 예외를 잡아서 처리 |
catch (e, s) | 예외 메시지(e)와 스택 추적(s)을 가져옴 |
on ExceptionType | 특정 예외만 처리 |
finally | 예외 발생 여부와 관계없이 항상 실행 |
throw | 예외를 발생시킴 |
rethrow | 현재 catch 블록에서 예외를 다시 던짐 |
사용자 정의 예외 | implements Exception을 사용하여 직접 예외 클래스를 정의 |
'Flutter for Beginners' 카테고리의 다른 글
Dart 객체지향 프로그래밍 - 클래스와 객체 (0) | 2025.02.24 |
---|---|
Dart 화살표 함수 (0) | 2025.02.21 |
Dart의 함수(Function)와 람다(Lambda) (0) | 2025.02.21 |
Dart의 제어문 (0) | 2025.02.20 |
Dart의 연산자 (0) | 2025.02.20 |