From 760f4a6a9c04a58d00f284e4cb26bb1f98fad0ef Mon Sep 17 00:00:00 2001 From: Remi Rousselet Date: Fri, 13 Oct 2023 16:39:02 +0200 Subject: [PATCH] Add log page --- website/docs/essentials/provider_observer.mdx | 62 +++++++++++++++++++ .../provider_observer/async_error.dart | 41 ++++++++++++ .../provider_observer/provider_observer.dart | 43 +++++++++++++ website/sidebars.js | 6 +- 4 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 website/docs/essentials/provider_observer.mdx create mode 100644 website/docs/essentials/provider_observer/async_error.dart create mode 100644 website/docs/essentials/provider_observer/provider_observer.dart diff --git a/website/docs/essentials/provider_observer.mdx b/website/docs/essentials/provider_observer.mdx new file mode 100644 index 000000000..0c71a041b --- /dev/null +++ b/website/docs/essentials/provider_observer.mdx @@ -0,0 +1,62 @@ +--- +title: Logging and error reporting +--- + +import { Link } from "../../src/components/Link"; +import { AutoSnippet, When } from "../../src/components/CodeSnippet"; +import providerObserver from "!!raw-loader!./provider_observer/provider_observer.dart"; +import asyncError from "!!raw-loader!./provider_observer/async_error.dart"; + +Riverpod natively offers a way to listen to all events happening +in the provider tree. +This can be used to log all the events, or to report errors to a +remote service. + +This is achieved by using the `ProviderObserver` class, +and passing it to `ProviderScope`/`ProviderContainer`. + +## Defining a ProviderObserver + +A `ProviderObserver` is a class that should be extended. +It offers various methods which can be overridden to listen to events: + +- `didAddProvider`, called when a provider is added to the tree +- `didUpdateProvider`, called when a provider is updated +- `didDisposeProvider`, called when a provider is disposed +- `providerDidFail`, when a synchronous provider throws an error + + + +:::caution +At the moment, if an error in an asynchronous provider is thrown, +the error will be received by the `didAddProvider`/`didUpdateProvider` methods +instead, with an `AsyncError` as value. +Note that this will be changed in the version 3.0 of Riverpod. + + + +::: + +## Using a ProviderObserver + +Now that we've defined an observer, we need to use it. +To do so, we should pass it to either `ProviderScope` or `ProviderContainer`: + +```dart +runApp( + ProviderScope( + observers: [ + MyObserver(), + ], + child: MyApp(), + ) +); +``` + +```dart +final container = ProviderContainer( + observers: [ + MyObserver(), + ], +); +``` diff --git a/website/docs/essentials/provider_observer/async_error.dart b/website/docs/essentials/provider_observer/async_error.dart new file mode 100644 index 000000000..8e80db1dd --- /dev/null +++ b/website/docs/essentials/provider_observer/async_error.dart @@ -0,0 +1,41 @@ +// ignore_for_file: avoid_print + +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/* SNIPPET START */ +class MyObserver extends ProviderObserver { + void handleValue(Object? value) { + if (value is AsyncError) { + print('Error: ${value.error}'); + } + } + + @override + void didAddProvider( + ProviderBase provider, + Object? value, + ProviderContainer container, + ) { + handleValue(value); + } + + @override + void didUpdateProvider( + ProviderBase provider, + Object? previousValue, + Object? newValue, + ProviderContainer container, + ) { + handleValue(newValue); + } + + @override + void providerDidFail( + ProviderBase provider, + Object error, + StackTrace stackTrace, + ProviderContainer container, + ) { + print('error: $error'); + } +} diff --git a/website/docs/essentials/provider_observer/provider_observer.dart b/website/docs/essentials/provider_observer/provider_observer.dart new file mode 100644 index 000000000..dd75afb01 --- /dev/null +++ b/website/docs/essentials/provider_observer/provider_observer.dart @@ -0,0 +1,43 @@ +// ignore_for_file: avoid_print + +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/* SNIPPET START */ +class MyObserver extends ProviderObserver { + @override + void didAddProvider( + ProviderBase provider, + Object? value, + ProviderContainer container, + ) { + print('Provider $provider was initialized with $value'); + } + + @override + void didDisposeProvider( + ProviderBase provider, + ProviderContainer container, + ) { + print('Provider $provider was disposed'); + } + + @override + void didUpdateProvider( + ProviderBase provider, + Object? previousValue, + Object? newValue, + ProviderContainer container, + ) { + print('Provider $provider updated from $previousValue to $newValue'); + } + + @override + void providerDidFail( + ProviderBase provider, + Object error, + StackTrace stackTrace, + ProviderContainer container, + ) { + print('Provider $provider threw $error at $stackTrace'); + } +} diff --git a/website/sidebars.js b/website/sidebars.js index d8eaed1b4..8d31d85f5 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -33,11 +33,7 @@ module.exports = { // }, "essentials/eager_initialization", "essentials/testing", - // { - // type: "link", - // label: "Logging and error reporting (WIP)", - // href: "https://github.com/rrousselGit/riverpod/tree/master/examples/marvel", - // }, + "essentials/provider_observer", "essentials/faq", "essentials/do_dont", ],