GlobalErrorObserver<St> class abstract

You may subclass GlobalErrorObserver and pass it to the store constructor, if you want to have a global observer for errors thrown in your actions:

var store = Store<AppState>(
  initialState: AppState(),
  globalErrorObserver: (store) => AppGlobalErrorObserver(),
}

class MyGlobalErrorObserver extends GlobalErrorObserver {
  @override
  void wrap() {
    // Do something.
  }
}

Your observer error object will be given all errors thrown in your actions (including those of type UserException), and also the errors thrown by the Persistor (and the cloud-sync) when persisting the state. Then:

  • If it returns the same error unaltered, this original error will be used.
  • If it returns something else, that it will be used instead of error.
  • If it returns null, error will be disabled (swallowed).

IMPORTANT: If instead of RETURNING an error you THROW an error inside the observe method, AsyncRedux will catch this error and use it instead of error. In other words, returning an error or throwing an error has the same effect. However, it is still recommended to return the error rather than throwing it.

Note this observer is called AFTER the action's ReduxAction.wrapError.

Errors not thrown by actions

Errors thrown by Persistor.persistDifference (for both the persistor and the cloudSync of the store) are also given to this observer, AFTER the persistor's Persistor.wrapError. In this case, the action will be null, and originalError will be the error before Persistor.wrapError. Then:

  • If it returns a UserException, it will be added to the store's error queue, so that it can be shown to the user (for example, by the UserExceptionDialog).
  • If it returns null, the error will be swallowed.
  • If it returns any other error, it will be thrown as an unhandled async error.

Use cases

  1. Use this to set up your app to use 3rd-party services like Sentry or Firebase Crashlytics to monitor your app for errors in production, and print them to the console in development and testing. Since you are setting it up in a centralized way, you don't have to "pollute" your code with logging calls.

  2. Use this to have a global place to convert some exceptions into UserExceptions. For example, Firebase may throw some PlatformExceptions in response to a bad connection to the server. In this case, you may want to show the user a dialog explaining that the connection is bad, which you can do by converting it to a UserException. Note, this could also be done in the ReduxAction.wrapError, but then you'd have to add it to all actions that use Firebase.

Parameters you can access in the observe method:

  • error: The error thrown by the action, AFTER wrapError.
  • originalError: The action error BEFORE wrapError.
  • stackTrace: The stack trace associated with the error.
  • action: The action that triggered the error, or null if the error didn't come from an action (for example, if it came from the Persistor).
  • store: Use it to read store.environment or store.configuration. Do not use it to dispatch new actions.
Implementers

Constructors

GlobalErrorObserver()

Properties

action ↔ ReduxAction<St>?
The action that threw the error.
latefinal
error ↔ Object
The error thrown by the action, AFTER being processed by the action's wrapError. If the error came from the Persistor (see action), this is the error AFTER being processed by Persistor.wrapError.
latefinal
hashCode → int
The hash code for this object.
no setterinherited
originalError ↔ Object
The error thrown by the action, BEFORE being processed by the action's wrapError. If the error came from the Persistor (see action), this is the error BEFORE being processed by Persistor.wrapError.
latefinal
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
stackTrace ↔ StackTrace
The stack trace of the error.
latefinal
store ↔ Store<St>
You can access the store, but do NOT use it to dispatch actions, because the store is still processing the current action, and dispatching another action may cause unexpected behavior. You can use it to read the environment, configuration, and state, if they are relevant to the error you want to return. Example:
getter/setter pair

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
observe() → Object?
Override this method to return the error you want to be used instead of the original error. Or, if you want to keep the original error, return it unaltered. If you want to disable the error, return null.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited