Shared Packages
How to add logging and safe crash reporting helpers to a Flutter app
Free Reference for app_utilities: every variable, option and package it generates. Command: archipelago generate app_utilities
Generate app_utilities, use the Log wrapper through DI, call the safe crash-report helpers, and see what the package leaves out.
What you'll learn
- Generating the
app_utilitiespackage - Using the
Logwrapper through DI - Using the safe crash-report helpers
- Knowing what the package does not include
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
New projects already include this brick. Every feature package depends on it for Log.
Step 1: Generate the Utilities Package
archipelago generate app_utilitiesThe prompts are:
- appName: the name of your app. It has no effect on the output.
- isForMonorepo: leave this as
true
Or use a config file:
{
"appName": "MyApp",
"isForMonorepo": true
}archipelago generate app_utilities --config utilities_config.jsonStep 2: Understand the Generated Structure
The package always lands at utilities/app_utilities/.
utilities/
└── app_utilities/
├── lib/
│ ├── app_utilities.dart
│ └── src/
│ ├── di/
│ │ ├── injector.dart # microPackage entry point
│ │ └── third_party_module.dart # Provides the shared Logger
│ ├── error/
│ │ └── safe_crash_reporter.dart
│ └── log/
│ ├── log.dart # Log wrapper and LogType enum
│ ├── filter/release_log_filter.dart
│ └── printer/simple_log_printer.dart
└── pubspec.yamlWith isForMonorepo: true, the hook adds the package to the workspace.
Step 3: Check the Registration
The app injector registers AppUtilitiesPackageModule as an external module. You do not wire it by hand.
Step 4: Use Log
Log is an injectable wrapper around the logger package:
@injectable
class PaymentUseCase {
PaymentUseCase(this._log);
final Log _log;
void run() {
_log.i('Starting work');
_log.consoleLazy(() => 'Details: ${computeDetails()}');
}
}Methods:
t,d,i,w,eandffor the six levelsconsole(message, type: LogType.info)for enum-based levelsconsoleLazy(() => message)skips building the string when logging is off
Step 5: Use the Safe Crash Reporters
Three top-level functions never throw. Call them at any point in the app lifecycle:
safeReportFatalCrash(error, stackTrace);
safeReportFlutterFatalCrash(details);
safeReportNonFatalCrash(error, stackTrace);Debug builds print to the console. Release builds go through the monitoring call that bootstrap.dart wires after DI starts.
Key Customization Points
| Customization | Where to Change |
|---|---|
| Log format | log/printer/simple_log_printer.dart |
| Which levels reach release logs | log/filter/release_log_filter.dart |
| Shared third-party objects | di/third_party_module.dart |
Limitations
The package has no extensions, no Result type and no debouncer. Add project helpers to a package of your own.