try-catch 구문은 Dart 언어의 예외 처리(exception handling) 메커니즘의 일부입니다.
여기서 예외란 프로그램의 정상적인 실행 흐름을 방해하는 사건입니다.
이는 코드작성의 오류, 네트워크 통신오류, 기기오류 등 다양하게 발생할 수 있습니다.
try-catch를 사용하여 실행 중 발생할 수 있는 예외(에러)를 포착하고 적절히 처리할 수 있습니다.
// 기본구조
try {
// 예외가 발생할 수 있는 코드
} catch (e) {
// 예외가 발생했을 때 실행되는 코드
}
try 블록
try {
// 예외가 발생할 수 있는 코드
}
예외가 발생할 수 있는 코드를 포함합니다.
여기서 예외가 발생하면 프로그램의 흐름이 try블록을 벗어나 가장 먼저 일치하는 catch블록으로 이동합니다.
catch(e) 블록
} catch (e) {
// 나머지 모든 예외를 처리하는 코드
}
위 블록에서 처리되지 않은 나머지 모든 예외를 처리합니다.
예외 타입에 상관없이 발생한 모든 예외를 잡아서 처리할 수 있습니다.
여기서 (e)는 발생한 예외 객체입니다.
예를들면
void main() {
String str = "123a";
try {
int number = int.parse(str);
print("Converted number: $number");
} catch (e) {
print("Error: $e");
}
}
// 출력 Error: FormatException: 123a
"123a"라는 문자열을 숫자(정수)로 변환할때 "a"라는 문자열이 섞여있기 때문에 변환이 되지 않습니다.
그렇기에 try에서의 매서드가 실행되지 않으니 catch쪽으로 넘겼고 "Error: $e" 가 나오는 모습입니다.
만약 여기서 "123a"가 아닌 "123"이면
catch문으로 넘어가지 않고 try문의 "Converted number : $number"가 정상적으로 출력이 되는것을 볼 수 있습니다.
여러개의 catch 블록
try {
// 예외가 발생할 수 있는 코드
} on SpecificException catch (e) {
// 특정 예외를 처리하는 코드
} on AnotherException catch (e) {
// 다른 특정 예외를 처리하는 코드
} catch (e) {
// 나머지 모든 예외를 처리하는 코드
}
다양한 유형의 예외를 별도로 처리할 수 있도록 여러 개의 catch블록을 사용할 수 있습니다.
void main() {
try {
// 예외가 발생할 수 있는 코드
throw FormatException("This is a FormatException");
} on FormatException catch (e) {
// FormatException 예외를 처리하는 코드
print("Caught a FormatException: $e");
} on IOException catch (e) {
// IOException 예외를 처리하는 코드
print("Caught an IOException: $e");
} catch (e) {
// 나머지 모든 예외를 처리하는 코드
print("Caught an unknown exception: $e");
}
}
이러한 형식처럼 여러번의 거름망을 사용할 수 있습니다.
여기서 FormatException나 IOException는 Dart에서 미리 정의된 예외 클래스입니다.
- Exception
- 모든 예외의 기본 클래스입니다.
- 사용자 정의 예외를 만들 때 주로 이 클래스를 상속합니다.
- Error
- 심각한 프로그램 오류를 나타내는 기본 클래스입니다.
- 주로 시스템에서 발생하는 오류에 사용됩니다.
- Error의 하위 클래스들은 시스템에서 심각한 문제를 나타냅니다.
- FormatException
- 잘못된 형식으로 인해 발생하는 예외입니다.
- 예를 들어, 문자열을 정수로 변환하려 할 때 해당 문자열이 숫자가 아닌 경우 발생할 수 있습니다.
- IOException
- 입출력(I/O) 작업 중에 발생하는 예외입니다.
- 예를 들어, 파일을 읽거나 쓸 때 발생하는 오류를 처리할 때 사용됩니다.
- IOException은 dart:io 라이브러리에 정의되어 있으므로 이를 사용하려면 해당 라이브러리를 임포트해야 합니다.
- ArgumentError
- 잘못된 인수가 함수에 전달될 때 발생합니다.
- RangeError
- 값이 허용된 범위를 벗어날 때 발생합니다.
- StateError
- 객체의 상태가 잘못되었을 때 발생합니다.
- TypeError
- 잘못된 타입이 사용될 때 발생합니다.
- UnimplementedError
- 구현되지 않은 기능이 호출될 때 발생합니다.
- 주로 미완성 메서드에서 사용됩니다.
- UnsupportedError
- 지원되지 않는 기능이 호출될 때 발생합니다.
- ConcurrentModificationError
- 객체가 반복 중에 수정될 때 발생합니다.
- 주로 컬렉션에서 사용됩니다.
import 'dart:io';
void main() {
try {
// 예외가 발생할 수 있는 코드
throw RangeError('Index out of range');
} on FormatException catch (e) {
print('Caught a FormatException: $e');
} on IOException catch (e) {
print('Caught an IOException: $e');
} on RangeError catch (e) {
print('Caught a RangeError: $e');
} on ArgumentError catch (e) {
print('Caught an ArgumentError: $e');
} on Exception catch (e) {
print('Caught a general exception: $e');
} catch (e) {
print('Caught an unknown exception: $e');
} finally {
print('This block is always executed.');
}
}
이러한식으로 여러개의 catch블록을 사용할 수 있습니다.
throw
throw 키워드는 Dart에서 예외를 발생시키는 데 사용됩니다.
예외 객체를 인수로 받아서 실행 중에 예외를 던지며 예외 객체는
위에 서술해두었던 Exception 클래스나 Error 클래스, 혹은 이들의 서브클래스여야 합니다.
또한, Dart에서는 어떤 객체라도 예외로 던질 수 있지만, 일반적으로는 Exception이나 Error를 사용합니다.
void main() {
try {
validateAge(-1);
} catch (e) {
print('Caught an exception: $e');
}
}
void validateAge(int age) {
if (age < 0) {
throw ArgumentError('Age cannot be negative');
} else {
print('Age is valid');
}
}
validateAge 함수는 age를 검사하여 음수인 경우 ArgumentError 예외를 던집니다.
main 함수는 validateAge 함수를 호출하고 try-catch 구문을 사용하여 예외를 처리합니다.
finally
finally 구문은 예외가 발생하든 발생하지 않든 상관없이 항상 특정 코드를 실행할 수 있게 해줍니다.
finally 블록은 예외 처리 후 자원 정리와 같은 작업에 유용합니다. (ex. 파일닫기)
import 'dart:io';
void main() {
File file = File('example.txt');
RandomAccessFile? raf;
try {
// 파일을 열고 내용을 읽음
raf = file.openSync(mode: FileMode.read);
String contents = raf.readStringSync(raf.lengthSync());
print('File contents: $contents');
} catch (e) {
// 예외를 처리하는 코드
print('An error occurred: $e');
} finally {
// 항상 실행되는 코드
// 파일을 닫는 작업
if (raf != null) {
raf.closeSync();
}
print('File closed');
}
}
이처럼 예외 발생 여부와 상관없이 항상 실행됩니다.
'Flutter > Dart Language' 카테고리의 다른 글
[플러터 Flutter] enum이란? (0) | 2024.07.31 |
---|---|
[플러터 flutter] initState와 dispose란? (0) | 2024.07.31 |
[플러터 flutter] 비동기 / 동기 async, awiat, future은 무엇인가? (0) | 2024.07.04 |
[플러터 Flutter] 초기화란? (0) | 2024.06.29 |
[플러터 Flutter] Const, Final의 차이 그리고 컴파일타임과 런타임 (0) | 2024.06.29 |