在 Flutter 中處理錯誤
Flutter 框架會捕捉在框架本身觸發的回呼期間發生的錯誤,包括在建構、佈局和繪製階段遇到的錯誤。不在 Flutter 回呼中發生的錯誤,框架無法捕捉,但您可以透過在 PlatformDispatcher
上設定錯誤處理程式來處理它們。
所有 Flutter 捕捉到的錯誤都會路由到 FlutterError.onError
處理程式。預設情況下,這會呼叫 FlutterError.presentError
,將錯誤轉儲到裝置記錄中。從 IDE 執行時,檢查器會覆蓋此行為,以便錯誤也可以路由到 IDE 的控制台,讓您可以檢查訊息中提到的物件。
當在建構階段發生錯誤時,會呼叫 ErrorWidget.builder
回呼,以建構用於取代失敗 Widget 的 Widget。預設情況下,在偵錯模式下,這會以紅色顯示錯誤訊息,而在發行模式下,這會顯示灰色背景。
當錯誤發生在呼叫堆疊上沒有 Flutter 回呼時,它們會由 PlatformDispatcher
的錯誤回呼處理。預設情況下,這只會列印錯誤,而不會執行其他任何動作。
您可以自訂這些行為,通常是在 void main()
函數中將它們設定為值。
以下說明每種錯誤類型的處理方式。在底部有一個程式碼片段,可以處理所有類型的錯誤。即使您可以直接複製貼上該程式碼片段,我們建議您先熟悉每種類型的錯誤。
Flutter 捕捉到的錯誤
#例如,若要讓您的應用程式在發行模式下,每次 Flutter 捕捉到錯誤時立即終止,您可以使用以下處理程式
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
FlutterError.onError = (details) {
FlutterError.presentError(details);
if (kReleaseMode) exit(1);
};
runApp(const MyApp());
}
// The rest of the `flutter create` code...
此處理程式也可以用於將錯誤回報給記錄服務。如需更多詳細資訊,請參閱我們的食譜章節,了解將錯誤回報給服務。
為建構階段錯誤定義自訂錯誤 Widget
#若要定義自訂的錯誤 Widget,在建構器無法建構 Widget 時顯示,請使用 MaterialApp.builder
。
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, widget) {
Widget error = const Text('...rendering error...');
if (widget is Scaffold || widget is Navigator) {
error = Scaffold(body: Center(child: error));
}
ErrorWidget.builder = (errorDetails) => error;
if (widget != null) return widget;
throw StateError('widget is null');
},
);
}
}
Flutter 未捕捉到的錯誤
#考慮一個 onPressed
回呼,它會調用非同步函數,例如 MethodChannel.invokeMethod
(或幾乎任何外掛程式)。例如
OutlinedButton(
child: const Text('Click me!'),
onPressed: () async {
const channel = MethodChannel('crashy-custom-channel');
await channel.invokeMethod('blah');
},
)
如果 invokeMethod
拋出錯誤,它不會轉送到 FlutterError.onError
。相反地,它會轉送到 PlatformDispatcher
。
若要捕捉此類錯誤,請使用 PlatformDispatcher.instance.onError
。
import 'package:flutter/material.dart';
import 'dart:ui';
void main() {
MyBackend myBackend = MyBackend();
PlatformDispatcher.instance.onError = (error, stack) {
myBackend.sendError(error, stack);
return true;
};
runApp(const MyApp());
}
處理所有類型的錯誤
#假設您想要在任何例外情況下退出應用程式,並且在建構 Widget 失敗時顯示自訂的錯誤 Widget - 您可以根據下一個程式碼片段處理您的錯誤
import 'package:flutter/material.dart';
import 'dart:ui';
Future<void> main() async {
await myErrorsHandler.initialize();
FlutterError.onError = (details) {
FlutterError.presentError(details);
myErrorsHandler.onErrorDetails(details);
};
PlatformDispatcher.instance.onError = (error, stack) {
myErrorsHandler.onError(error, stack);
return true;
};
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, widget) {
Widget error = const Text('...rendering error...');
if (widget is Scaffold || widget is Navigator) {
error = Scaffold(body: Center(child: error));
}
ErrorWidget.builder = (errorDetails) => error;
if (widget != null) return widget;
throw StateError('widget is null');
},
);
}
}
除非另有說明,本網站的文件反映 Flutter 的最新穩定版本。頁面最後更新於 2024-06-24。 檢視原始碼 或 回報問題。