플러터 웹뷰 Navigation Decision 에러 해결하지

소요 시간: 2분

오늘은 Flutter 앱에서 발생한 에러를 해결하는 데 시간을 보냈다. 에러 메시지는 다음과 같았다:

The body might complete normally, causing 'null' to be returned, but the return type, 'FutureOr<navigationdecision>', is a potentially non-nullable type. Try adding either a return or a throw statement at the end.

이 에러는 onNavigationRequest 함수에서 NavigationDecision을 반환하지 않는 경로가 존재한다는 것을 나타냈다. 이 메서드는 비동기적으로 실행되기 때문에 특정 조건에서 NavigationDecision을 반드시 반환해야 한다. 만약 아무런 값을 반환하지 않으면 기본적으로 null이 반환되는데, 이는 FutureOr<NavigationDecision>과 맞지 않아 오류가 발생하게 된다.


문제 원인

문제를 해결하기 위해 코드의 흐름을 면밀히 분석해봤다. 각 조건문이 어떻게 작동하는지, 그리고 반환 값이 없는 경우가 있는지를 점검했다. 기본적으로 모든 경로에서 적절한 NavigationDecision을 반환해야 한다는 사실을 깨달았다.


수정된 코드

아래는 수정한 onNavigationRequest 함수의 코드이다:

onNavigationRequest: (NavigationRequest request) async {
  // 생략 ...
  if (isAllowedInAppLink(finalUrl)) {
    return NavigationDecision.navigate;
  } else if (uri.scheme == 'http' || uri.scheme == 'https') {
    debugPrint('Opening in external browser: ${request.url}');
    if (await canLaunchUrl(uri)) {
      await launchUrl(
        uri,
        mode: LaunchMode.externalApplication,
      );
      return NavigationDecision.prevent; // Prevent navigation in the WebView
    } else {
      // This path will never reach a return statement, throw an exception instead
      throw 'Could not launch $request.url';
    }
  }
  // If none of the conditions are met, you need to return a default NavigationDecision
  return NavigationDecision.prevent; // Prevent navigation for any other URL
}

if문 경로마다 적절한 return 값을 추가하였다.


주요 수정 사항

내가 수정한 코드 일부분의 내용은 다음과 같다.

플러터 리스트