티스토리 뷰
try-catch 구문은 Dart에서 런타임 동안 발생할 수 있는 오류를 처리하기 위한 방법
예외가 발생할 수 있는 구문을 try로 감싸고, catch에서 해당 예외를 처리하게 됨
try {
//예외 발생 가능성 있는 구문
} catch(exception, stackTrace) {
//예외 처리
}
Throw
예외를 던지거나 발생시킬 때는 throw라는 키워드를 쓰면 됨
throw FormatException('Expected at least 1 section');
아래처럼 단순히 임의의 객체(여기서는 String 타입)를 에러로 발생시킬 수 있음
하지만 이렇게 임의의 객체들로 예외를 발생시키다보면, 관리가 어려워지고 가독성이 떨어지기 때문에 제대로 된 설계가 필요.
throw 'Out of llamas!';
Catch
"예외를 잡아서 처리하는 부분"
catch는 2개의 인자를 받는데, 하나는 필수 인자로 발생한 예외 객체, 나머지 하나는 선택 인자로 StackTrace타입의 객체임
- 첫 번째 인자 (exception) : 필수
예외 객체 자체. 발생한 예외의 구체적인 정보와 메시지 등이 포함
- 두 번째 인자 (stackTrace) : 선택
StackTrace의 객체로 예외가 발생한 위치와 호출 스택의 정보를 포함. 이를 통해 예외가 발생한 위치 등을 추적할 수 있음
Catch로 예외 처리하기
1. 일반적인 처리
가장 기본적으로는 아래처럼 catch 구문에서 모든 예외들을 받아서 처리할 수 있음
try {
throw FormatException('This is a format exception');
} catch (e) {
print('Caught an exception: $e');
}
//Caught an exception: FormatException: This is a format exception
2. 예외별 처리
1번처럼 catch에서 모든 예외를 처리하는 게 아닌, 예외 타입별로 처리하는 방법도 있음
예외에도 Exception, FormatException, HttpException 등 여러 종류가 있고, 예외별로 처리가 가능함
on이라는 키워드와 해당 타입을 써주면 그 타입의 예외를 처리하는 구문이 됨
try {
throw FormatException('This is a format exception');
} on FormatException catch (e) {
print('Caught a FormatException: $e');
} on IOException catch (e) {
print('Caught an IOException: $e');
} catch (e) {
print('Caught an exception: $e');
}
//Caught a FormatException: FormatException: This is a format exception
위 코드를 보면 해당 예외 타입에 따라 처리를 하고 있고 FormatException을 처리하는 catch 구문으로 빠져 처리되는 걸 알 수 있음
위 처리는 catch에서 모든 예외를 다 받은 후 처리해도 됨
동일한 결과가 나옴
try {
throw FormatException('This is a format exception');
} catch (e) {
if (e is FormatException) {
print('Caught FormaException: $e');
} else if (e is IOException) {
print('Caught FormaException: $e');
} else {
print('Caught Exception: $e');
}
}
//Caught a FormatException: FormatException: This is a format exception
예외를 catch할 필요가 없을 때는 굳이 catch라는 키워드를 써주지 않아도 됨!
아래 코드에서 OutOfLlamasException은 예외 객체가 필요없기 때문에 따로 catch 키워드를 쓰지 않았음
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
} on Exception catch (e) {
print('Unknown exception: $e');
} catch (e) {
print('Something really unknown: $e');
}
Custom Exception
말그대로 Exception도 Custom으로 만들 수 있음.
기존의 Exception을 implements 해서 구현하면 됨
class ValidationException implements Exception {
final String message;
ValidationException(this.message);
@override
String toString() => 'ValidationException: $message';
}
이렇게 만든 Custom Exception을 기존 예외 타입으로 써주면 됨!
try {
throw ValidationException('This is a custom exception');
} on ValidationException catch (e) {
print('Caught custom Exception: $e');
} catch (e) {
print('Caught Exception: $e');
}
//Caught custom Exception: ValidationException: This is a custom exception
Finally
try-catch 문에서 함께 사용되는 블록으로, try-catch에서 예외가 발생했는지 여부와 상관없이 try-catch 실행 후 항상 실행되는 구문
finally 블록은 사용 중이던 모든 리소스를 정리하는 데 사용됨
메모리 관리에 도움을 주고 누수를 방지하며 최적의 리소스 사용을 보장해줌
try {
throw FormatException('This is a format exception');
} catch (e) {
if (e is FormatException) {
print('Caught FormaException: $e');
} else if (e is IOException) {
print('Caught FormaException: $e');
} else {
print('Caught Exception: $e');
}
} finally {
print('-----Everything is done!');
}
//Caught FormaException: ValidationException: This is a custom exception
//-----Everything is done!
rethrow
rethrow란 말 그대로 예외를 다시 던지게 해주는 키워드
기존의 예외 Stack Trace를 그대로 유지하기 때문에 예외 발생 위치와 관련된 정보를 잃지 않고 처리할 수 있게 도와줌
실제로 코드를 쓰다 보면 try-catch 구문을 상위에서 또 호출하는 경우가 많기 때문에 기존의 정보를 잃지 않게 도와주는 건 디버깅 목적에도 큰 도움이 됨!
아래처럼 rethrow로 해당 예외를 상위로 다시 던질 때, 같은 예외 발생과 함께 어디서 발생했는지를 알 수 있음!
void intermediateFunction() {
try {
throw FormatException('This is a FormatException');
} catch (e) {
print('[rethrow] intermediateFunction() caught an exception: $e');
rethrow; // 예외를 다시 던짐
}
}
void main() {
//intermediateFunction를 호출하는 상위 호출부
try {
intermediateFunction();
} catch (e, s) {
print('==================');
print('main() caught an exception: $e');
print('==================');
print('Stack trace: $s');
}
}
/*
[rethrow] intermediateFunction() caught an exception: FormatException: This is a FormatException
==================
main() caught an exception: FormatException: This is a FormatException
==================
Stack trace: #0 functionThatThrows (file:///home/runner/Dart/main.dart:22:3)
#1 intermediateFunction (file:///home/runner/Dart/main.dart:27:5)
#2 main (file:///home/runner/Dart/main.dart:36:5)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
*/
try-catch 또한 많이 사용하고 있었지만, 제대로 된 정리 없이 쓰고 있었던 듯하다
특히 finally라는 건 이번에 처음 알게 되었는데, 꽤 유용하게 활용할 수 있을 것 같다!
https://dart.dev/language/error-handling
Error handling
Learn about handling errors and exceptions in Dart.
dart.dev
'Flutter' 카테고리의 다른 글
[간단 Tip] Barrel, part, part of (0) | 2024.07.19 |
---|---|
ProxyProvider 간단 사용 예제 (0) | 2024.07.16 |
addPostFrameCallback를 사용한 error 해결 (0) | 2024.07.09 |
Form 필드로 유효성 체크하기 (1) | 2024.07.02 |
Kodeco Flutter 면접 질문_Junior Written Questions2 (0) | 2024.06.25 |
- Total
- Today
- Yesterday