[Dart 언어강좌] 024. Dart에서의 에러 처리, 사용자 정의 예외 만들기

1. Dart에서 에러 처리의 중요성

에러 처리는 어떤 프로그래밍 언어든지 중요한 개념입니다. Dart 언어는 개발자에게 코드의 안정성과 신뢰성을 보장하기 위해 다양한 에러 처리 메커니즘을 제공합니다. 에러 처리란 예상치 못한 상황에서 프로그램이 중단되지 않고, 적절한 조치를 취할 수 있게 하는 프로세스를 의미합니다. Dart에서는 예외(Exception)와 오류(Error)를 구분하여 처리합니다. 이 두 가지는 모두 프로그램 실행 중 발생할 수 있는 문제를 나타내지만, 그 처리 방식이 다릅니다.

2. Dart의 기본적인 에러 처리

Dart에서 에러를 처리하는 가장 기본적인 방법은 try-catch 문을 사용하는 것입니다. try 블록 안에서 코드 실행 중에 발생할 수 있는 예외를 처리하고, catch 블록에서는 실제로 에러를 처리하는 로직을 작성합니다. 다음은 기본적인 예제입니다:

void main() {
                try {
                    var result = 10 ~/ 0; // 0으로 나누기, 예외 발생
                    print(result);
                } catch (e) {
                    print('예외 발생: $e');
                }
            }

위 코드에서 10을 0으로 나누려는 시도는 IntegerDivisionByZeroException을 발생시킵니다. 이를 catch 블록에서 잡아내어 ‘예외 발생’ 메시지를 출력하게 됩니다.

3. Dart의 에러와 예외

Dart에서는 ErrorException을 구분합니다. Error는 보통 치명적인 문제로, 애플리케이션이 이를 회복할 수 없다는 것을 의미합니다. 반면, Exception은 프로그램이 예측 가능한 예외 상황으로, 이에 대한 처리가 가능합니다. 예를 들어, 파일을 열거나 네트워크 요청을 하는 경우가 예외로 처리될 수 있습니다.

에러와 예외를 구분하는 것은 오류를 정교하게 다루고, 애플리케이션의 신뢰성을 높이는 데 매우 중요합니다.

4. 사용자 정의 예외 만들기

때때로 기본 제공되는 예외로는 충분하지 않은 경우가 있습니다. 이럴 때는 사용자 정의 예외를 만들어 사용할 수 있습니다. 사용자 정의 예외는 일반적으로 Exception 클래스를 상속하여 만듭니다. 다음은 사용자 정의 예외 클래스를 만드는 예제입니다:

class MyCustomException implements Exception {
                String cause;
                MyCustomException(this.cause);
            }

            void main() {
                try {
                    throw MyCustomException('사용자 정의 예외 발생');
                } catch (e) {
                    print('예외: ${e.cause}');
                }
            }

위 코드에서 MyCustomException이라는 사용자 정의 예외 클래스를 만들었습니다. main 함수에서 이를 던지면 catch 블록에서 해당 예외의 원인을 출력할 수 있습니다.

5. 예외 발생 시 사용자 정의 정보 추가하기

사용자 정의 예외 클래스에 추가적인 정보를 담기 위해 속성을 추가할 수 있습니다. 예를 들어, 에러 코드나 발생한 메서드의 이름을 추가해주면, 나중에 오류를 추적하는 데 유용합니다.

class MyCustomException implements Exception {
                String cause;
                int errorCode;
                MyCustomException(this.cause, {this.errorCode = 0});
            }

            void main() {
                try {
                    throw MyCustomException('사용자 정의 예외 발생', errorCode: 404);
                } catch (e) {
                    print('예외: ${e.cause}, 에러 코드: ${e.errorCode}');
                }
            }

위의 코드에서는 errorCode 속성을 추가하여 예외에 대한 추가 정보를 제공하고 있습니다. 이처럼 사용자 정의 예외를 통하여 다양한 정보를 포함시킬 수 있습니다.

6. 다중 예외 처리

상황에 따라 여러 종류의 예외가 발생할 수 있습니다. Dart에서는 catch 문을 여러 번 사용하여 다양한 예외를 처리할 수 있습니다. 이는 예외의 유형을 구분하여 보다 세밀하게 제어하는 데 유용합니다.

void main() {
                try {
                    var result = 10 ~/ 0; // 예외 발생
                } catch (e) {
                    if (e is IntegerDivisionByZeroException) {
                        print('0으로 나누는 이 예외를 처리했습니다: $e');
                    } else {
                        print('다른 예외: $e');
                    }
                }
            }

위의 예제에서는 발생한 예외가 IntegerDivisionByZeroException인지 체크하여 각각의 경우에 따른 처리를 다르게 하고 있습니다.

7. 비동기 예외 처리

Dart는 비동기 프로그래밍을 지원하기 위해 Futureasync/await 구문을 제공합니다. 비동기 코드에서 예외가 발생할 경우, try-catch 블록을 사용하여 예외를 처리할 수 있습니다. 다음은 비동기 프로그래밍에서의 예외 처리 예시입니다:

Future fetchData() async {
                throw Exception('비동기 예외 발생');
            }

            void main() async {
                try {
                    await fetchData();
                } catch (e) {
                    print('비동기 예외: $e');
                }
            }

위 코드에서는 fetchData라는 비동기 함수에서 예외를 던지며, 이를 main 함수에서 처리하고 있습니다. 비동기 처리에서는 항상 await 키워드를 사용하여 예외를 잡을 수 있도록 해야 합니다.

8. 마지막 정리

Dart에서의 예외 처리는 코드의 안정성과 신뢰성을 높이는 데 큰 역할을 합니다. 사용자 정의 예외를 활용하면 애플리케이션의 특정 요구사항을 충족하는 보다 세밀한 에러 처리가 가능합니다. 예외를 처리하는 방법과 관련하여 우리의 코드가 예측 가능한 경로를 따라 안전하게 실행될 수 있도록 만들어주는 것이 바로 에러 처리의 핵심입니다. 항상 올바른 예외 처리를 통해 개발의 질을 높이고, 사용자에게 좋은 경험을 제공해야 합니다.