Search code examples
flutterbloc

In Flutter, how to catch detail of NULL exception?


In my project, I use BLOC pattern with Stream. That stream watch Loading, Data and Error state then show to UI that states.

  • At first scenario, if in model file there is contain null value, UI only show loading state and in console show the detail of which API value contain null value. So I can easily fix.
  • In second scenario, Later in BLOC function,I add try{} catch(e){} to show in the UI for the exact detail of error instead of Loading State when API contain null value. But I face a problem that is it show error like Null check operator used on a null value not only on UI screen but also in console but I can't find automatically (mean at first scenario, from console can check which value contain from console ) which detail API value contain null and manually check the API and model. It only show error in console about abstract fact of the model class that contain null.

So how can I fix that problem? I want to not only show error on screen instead of loading when API contain null value but also want to check automatically null value from console.

This is my code and show error for first scenario without try catch and exception state

getNotificationDetail({required String notificationId}) async {
    await _notificationRepository
        .getNotificationDetail(
      getNewNotificationEndPoint: END_POINT_NOTIFICATION_DETAIL,
      notificationId: notificationId,
    )
        .then(
          (responseValue) {
        _notificationDetailController.sink.add(MessageState.loading);
        if (responseValue?.messageState == MessageState.data) {
          notificationDetailModel = responseValue!.data;
          notificationDetailData = notificationDetailModel!.data;
          _notificationDetailController.sink.add(MessageState.data);
        } else if (responseValue?.messageState == MessageState.requestError) {
          errorHandlingModel = responseValue?.data;
          _notificationDetailController.sink.add(MessageState.requestError);
        } else if (responseValue?.messageState == MessageState.serverError) {
          _notificationDetailController.sink.add(MessageState.serverError);
        }
      },
    );
  }
E/flutter (22630): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'int'
E/flutter (22630): #0      new NewNotificationCountData.fromJson (XXXXXXXXXX/model/notification_model/new_notification_count_model.dart:39:19)

This is my code and show error for second scenario with try catch and exception state

getNotificationDetail({required String notificationId}) async {
    try {
      await _notificationRepository
          .getNotificationDetail(
        getNewNotificationEndPoint: END_POINT_NOTIFICATION_DETAIL,
        notificationId: notificationId,
      )
          .then(
        (responseValue) {
          _notificationDetailController.sink.add(MessageState.loading);
          if (responseValue?.messageState == MessageState.data) {
            notificationDetailModel = responseValue!.data;
            notificationDetailData = notificationDetailModel!.data;
            _notificationDetailController.sink.add(MessageState.data);
          } else if (responseValue?.messageState == MessageState.requestError) {
            errorHandlingModel = responseValue?.data;
            _notificationDetailController.sink.add(MessageState.requestError);
          } else if (responseValue?.messageState == MessageState.serverError) {
            _notificationDetailController.sink.add(MessageState.serverError);
          }
        },
      );
    } catch (e) {
      errorMessage = e.toString();
      _notificationDetailController.sink.add(MessageState.exception);
    }
  }
The following _CastError was thrown building StreamBuilder<MessageState>(dirty, state: _StreamBuilderBaseState<MessageState, AsyncSnapshot<MessageState>>#aa511):
Null check operator used on a null value

The relevant error-causing widget was: 
  StreamBuilder<MessageState> StreamBuilder:file:///XXXXXXXXXXX/lib/modules/notifications/view_items/notification_detail_body.dart:29:13
When the exception was thrown, this was the stack: 

Solution

  • Using with StackTrace (st) try{} catch(e,st){} solved what I expected. Thanks for answering @pskink comment.

    So I change my code with

    getNotificationDetail({required String notificationId}) async {
        try {
          await _notificationRepository
              .getNotificationDetail(
            getNewNotificationEndPoint: END_POINT_NOTIFICATION_DETAIL,
            notificationId: notificationId,
          )
              .then(
            (responseValue) {
              _notificationDetailController.sink.add(MessageState.loading);
              if (responseValue?.messageState == MessageState.data) {
                notificationDetailModel = responseValue!.data;
                notificationDetailData = notificationDetailModel!.data;
                _notificationDetailController.sink.add(MessageState.data);
              } else if (responseValue?.messageState == MessageState.requestError) {
                errorHandlingModel = responseValue?.data;
                _notificationDetailController.sink.add(MessageState.requestError);
              } else if (responseValue?.messageState == MessageState.serverError) {
                _notificationDetailController.sink.add(MessageState.serverError);
              }
            },
          );
        } catch (e, st) {
          errorMessage = e.toString();
          _notificationDetailController.sink.add(MessageState.exception);
          print('st === $st');
        }
      }