Flutter에서의 함수형 에러 처리
Dart 언어는 에러를 처리하기 위해 try, catch, 그리고 throw와 같은 기본적인 메커니즘을 제공한다. 하지만 함수형 프로그래밍(FP)을 활용하면 더 명확하고 안전한 방식으로 에러를 처리할 수 있다. 이 글에서는 Flutter에서 fpdart 패키지의 Either 타입을 활용한 함수형 에러 처리 방법을 소개한다.
함수형 프로그래밍이란?
함수형 프로그래밍(FP)은 다음과 같은 특징을 지닌 프로그래밍 패러다임이다.
- 순수 함수: 동일한 입력에 대해 항상 동일한 출력을 반환하며, 외부 상태를 변경하지 않음
- 불변성: 데이터가 변경되지 않으며, 새로운 데이터는 기존 데이터를 복사하여 생성
- 선언적 스타일: "무엇을" 해야 하는지에 집중하며, "어떻게" 해야 하는지는 추상화
이는 객체지향 프로그래밍(OOP)과 대비된다. OOP는 상태 변화와 명령형 스타일을 기반으로 객체의 데이터와 동작을 정의한다.
Dart와 같은 현대 언어는 FP와 OOP를 모두 지원하므로, 필요에 따라 두 가지 스타일을 혼합하여 사용할 수 있다.
예제: 런타임 에러 처리
예를 들어, String 타입의 숫자 값을 double로 변환하려면 다음과 같이 작성할 수 있다.
final value = double.parse('155.50');
여기서 만약 숫자가 아닌 값을 입력하면 런타임에서 예외가 발생한다.
final value = double.parse('not-a-number'); // FormatException 발생
공식문서에 따르면, double.parse 함수의 시그니처는 아래와 같다.
static double parse(String source);
이를 처리하기 위해 try/catch 블록을 사용할 수 있다.
try {
final value = double.parse('not-a-number');
// 성공 처리
} on FormatException catch (e) {
// 에러 처리
print(e);
}
하지만 대규모 코드베이스에서는 어떤 함수가 예외를 던질 수 있는지 파악하기 어려울 수 있다. 이상적으로는 함수 시그니처에서 에러 가능성을 명시적으로 나타내야 한다.
Either 타입
fpdart 패키지의 Either 타입은 함수 시그니처에서 성공과 실패를 명시적으로 표현할 수 있도록 도와준다.
import 'package:fpdart/fpdart.dart';
Either<FormatException, double> parseNumber(String value) {
try {
return Either.right(double.parse(value)); // 성공 시 반환
} on FormatException catch (e) {
return Either.left(e); // 실패 시 반환
}
}
- Either.left : 에러를 나타냄
- Either.right : 성공 값을 나타냄
위 코드에서 Either<FormatException, double>은 이 함수가 FormatException 또는 double 값을 반환할 수 있음을 명확히 보여준다.
Result 타입과의 비교
Either는 multiple_result 패키지의 Result 타입과 유사하다.
Result<FormatException, double> parseNumber(String value) {
try {
return Success(double.parse(value)); // 성공 시 반환
} on FormatException catch (e) {
return Error(e); // 실패 시 반환
}
}
- Success ↔ Either.right
- Error ↔ Either.left
다만 Either는 더욱 강력하고 다양한 API를 제공한다.
tryCatch 팩토리 생성자
tryCatch 팩토리 생성자를 사용하면 코드를 더욱 간소화할 수 있다.
Either<FormatException, double> parseNumber(String value) {
return Either.tryCatch(
() => double.parse(value),
(e, _) => e as FormatException,
);
}
구현방식
factory Either.tryCatch(
R Function() run, L Function(Object o, StackTrace s) onError) {
try {
return Either.of(run());
} catch (e, s) {
return Either.left(onError(e, s));
}
}
- 첫 번째 매개변수는 실행할 함수이다.
- 두 번째 매개변수는 에러와 스택 트레이스를 받아 처리하는 콜백이다.
위 예시에서는 double.parse가 항상 FormatException만 던지므로 안전하게 캐스팅(as FormatException)할 수 있다.
결론
Flutter에서도 함수형 프로그래밍을 활용한 에러 처리가 가능하다. 특히, fpdart 패키지의 Either<L, R> 타입은 다음과 같은 장점을 제공한다.
- 함수 시그니처에 에러 가능성을 명시적으로 표현하여 코드 가독성과 안정성을 높임
- 컴파일 타임에 에러 처리를 강제하여 런타임 오류를 줄임
- 다양한 메서드(map, mapLeft, fold, 등)를 통해 데이터를 유연하게 조작 가능
이러한 접근법은 특히 대규모 프로젝트나 복잡한 비즈니스 로직이 포함된 애플리케이션에서 유용하다. FP 스타일로 코드를 작성하면 더 안전하고 유지보수가 용이한 애플리케이션을 개발하는데 도움이 될 것이라 생각한다.
아래 링크의 포스팅을 참고하여 정리한 내용입니다. 원문을 확인하고 싶으시면 아래 링크를 확인해주세요.
출처 - https://flutterexperts.com/functional-error-handling-in-flutter/
'Personal Posting > Flutter' 카테고리의 다른 글
Flutter에서 Hooks 사용하기 (0) | 2025.01.06 |
---|---|
Dart/Flutter 프로토타입 디자인 패턴 (0) | 2025.01.04 |
SOLID 원칙 Flutter 프로젝트에 적용하기 (1) | 2025.01.03 |
Secure API key 사용 (1) | 2025.01.03 |
Flutter에서 Android MacAddress 에러 (0) | 2024.04.23 |