Handle Exceptions from the Web API

This section will cover guidelines on how to handle exceptions from Web API in the GIRAF apps.

Guidelines

  • Use OnError function when listening to a stream: Listen().OnError to catch the error.
  • Add a case with the requested ErrorCode in the switch statement within getErrorMessage method

How to Use a Stream

In order to be able to get values from a stream you need to do something referred to as subscribing or listening. When you subscribe to a stream you will only get the values that are emitted (put onto the stream) after the subscription. You subscribe to the stream by calling the listen function and supplying it with a method to call back to when there's a new value available, commonly referred to as a callback method, or just a callback.

Catching an API Error from a Stream in the Apps

The listen call returns a StreamSubscription with the type of the stream. With a stream subscription it is possible to use the onError function, which takes and error object and the stack trace as parameters. An example of onError usage on a listen call from new_citizen_screen.dart on the weekplanner can be seen below.

1
2
3
4
5
6
7
8
9
onPressed: () {
   _bloc.createCitizen().listen((GirafUserModel response) {
     if (response != null) {
       Routes.pop<GirafUserModel>(context, response);
       _bloc.resetBloc();
     }
   }).onError((Object error) =>
       _translator.catchApiError(error, context));
}

_translator is the referenced ApiErrorTranslater class that holds the catchApiError method. This class is found in errorcode_translater.dart. Referring to this class is done by instantiating the class: final ApiErrorTranslater _translator = ApiErrorTranslater(); The class ApiErrorTranslater holds two methods: catchApiError and getErrorMessage.

Catching API errors method

The catchApiError method builds a pop up GirafNotifyDialog. The string for the error message is received from the other method getErrorMessage.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void catchApiError(Object error, BuildContext context) {
   showDialog<Center>(

   /// exception handler to handle web_api exceptions
   barrierDismissible: false,
   context: context,
   builder: (BuildContext context) {
   return GirafNotifyDialog(
   title: 'Fejl',
   description: getErrorMessage(error),
   key: const Key('ErrorMessageDialog'));
   });
}  

Creating new error message method

In this method you will need to add a new case for a specific ErrorKey with a return call on an error message string.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
///Get apropriate error message based on error code
  String getErrorMessage(ApiException error) {
    switch (error.errorKey) {
        case ErrorKey.UserAlreadyExists:
        return 'Brugernavnet eksisterer allerede';
      case ErrorKey.Error:
        // Undefined errors, the message is in english
        // as we cant predict why it was cast
        return 'message: ' +
            error.errorMessage +
            '\nDetails: ' +
            error.errorDetails;
      default:
        return 'Ukendt fejl';
    }
  }

Last update: December 12, 2023