[譯] 使用 Catcher 處理 Flutter 錯誤

說明:這是一篇介紹 Flutter 錯誤處理的文章,翻譯自國外的一篇博客,如有翻譯不許確或文字表達上的不足之處,歡迎指正。原文連接:https://medium.com/flutter-community/handling-flutter-errors-with-catcher-efce74397862
做者:
Jakub Homlala


本圖片源自UnsplashChor Hung Tsanggit

錯誤處理是程序員天天的工做,這事兒在平常工做中是沒完沒了的。在 Dart 語言中,咱們能夠用 try-catch 語言結構輕鬆地處理錯誤。可是,若是咱們忘了寫 try-catch 代碼會怎樣?咱們會獲得一個像下面這樣的「紅屏錯誤頁面」。程序員


是的,咱們的代碼不都老是運行良好。每個開發者都會有疏忽。但好的開發者會解決他所犯的失誤。github

對用戶來講,一個重要的事情是,當咱們是一個 APP 的用戶的時候,咱們須要知道一些超出預期的事發生了,而且咱們能夠決定是否發送錯誤日誌給開發者。錯誤日誌會幫助開發者修復錯誤。後端

開發者能修復錯誤,但他們須要知道發生了什麼錯誤和在哪兒發生的錯誤。在移動應用開發中,咱們須要一個能夠報告程序異常行爲給開發者的工具。目前,在 Flutter 中咱們已經支持了 Sentry 錯誤追蹤功能,很快也會支持 Firebase 的 Crashlytics。可是,若是咱們不想使用 Sentry 或 Crashlytics 怎麼辦呢?若是咱們使用一些配置簡單,還能夠在開發階段甚至在已發佈後捕獲錯誤的通用的工具,那該怎麼實現呢?這個工具包含發送郵件的功能,用戶只需點擊「發送」 就能夠把錯誤反饋給開發者,或者把崩潰日誌保存到設備的存儲器中。這就是接下來將要介紹的 Catcher 了。安全

Catcher 簡介


Catcher 的 logobash

Catcher 是一個新的捕獲和處理錯誤信息的 Flutter 插件。Catcher 提供多種錯誤報告模型和處理程序,以配合 Flutter 應用程序。Catcher 深受 ACRA 的啓發。服務器

Catcher 報告流程是很容易理解的(參看下圖)。Catcher 將錯誤處理程序注入到你的應用程序中,從而能夠捕獲全部未經檢測的錯誤。一旦它捕獲到錯誤,他就建立報告並將其發送到reporter 中。reporter 顯示錯誤的相關信息並等待用戶決策。若是用戶接受報告錯誤,則處理程序(handlers)將處理該報告。app

你也能夠報告你在 try catch 中檢查到的錯誤。async

Catcher 也會收集用戶設備硬件和操做系統的信息。這些數據的獲取是能夠不經用戶任何形式的受權,由於它不含有用戶的我的信息。這些數據是頗有幫助的,由於有些時候產生錯誤是由於設備的問題而不是開發者的問題。ide


Catcher 原理圖

如何使用 Catcher

讓咱們看一個使用 Catcher 的基本例子。首先咱們須要安裝插件。到你的 pubspec.yaml 文件中加上下面內容:

dependencies:
  catcher: ^0.0.8複製代碼

而後,你須要執行 packages get 命令下載和安裝到你的項目中。

最後一步是加上這一句 import:

import ‘package:catcher/catcher_plugin.dart';複製代碼

咱們已經準備好使用 Catcher了,下面就是使用 Catcher 的基本例子。

main() {
  //debug configuration  CatcherOptions debugOptions =
      CatcherOptions(DialogReportMode(), [ConsoleHandler()]);

  //release configuration
  CatcherOptions releaseOptions = CatcherOptions(DialogReportMode(), [
    EmailManualHandler(["recipient@email.com"])  ]);

  //profile configuration
  CatcherOptions profileOptions = CatcherOptions(
    NotificationReportMode(),
    [ConsoleHandler(), ToastHandler()],
    handlerTimeout: 10000,
    customParameters: {"example": "example_parameter"},
  );
  //MyApp is root widget
  Catcher(MyApp(),
      debugConfig: debugOptions,
      releaseConfig: releaseOptions,
      profileConfig: profileOptions);
}複製代碼

一般狀況下,當你執行你的代碼,你的 main 函數只有這一行:runApp(MyApp()); ,這一行代碼用來啓動應用。當你使用 Catcher 的時候,你將再也不使用這一行代碼。替代上面的方式,你須要用根 Widget 和 應用配置建立 Catcher 實例。

Catcher 容許你同時設置 3 種配置: debug , releaseprofile 。在上面的代碼中,咱們建立了 3 個 CatcherOptions 實例,分別描述 Catcher 在不一樣模式下的行爲方式。當應用運行在 debug 環境時,Catcher 會使用 debugConfig ,當應用運行在發佈環境時會使用 releaseConfig 當運行在 「profile」 模式時,會使用 profileConfig

在每個 CatcherOptions 實例中,你能夠配置不一樣的 報告模型和處理程序列表。點擊這裏能夠查看 CatcherOptions 的全部的配置參數。

有 4 種報告模式:

  • 靜默報告模式
  • 通知報告模式
  • 對話框報告模式
  • 頁面報告模式

有 6 種處理程序類型:

  • Console 處理程序
  • Http 處理程序
  • 文件處理程序
  • Toast 處理程序
  • 自動郵件處理程序
  • 手動郵件處理程序


當你建立 Catcher 實例的時候,它將會啓動你的根 Widget 並偵聽應用程序中發生的任何錯誤。在調試模式下運行上面的代碼,一旦有錯誤發生,將會顯示一個對話框,用戶能夠在對話框中作出是否報告錯誤的決策。一旦用戶接受報告錯誤,錯誤將由 Console 處理程序處理錯誤並將錯誤信息簡單地打印到 Console 中。

你能夠在這裏找到基礎示例的完整代碼。



使用對話框報告模式和 Console 處理程序的基礎示例,Console 中顯示了完整的報告數據

報告模式

讓咱們談一談報告的模式。如你所知,報告模式是咱們向用戶顯示錯誤信息的方式。下面,讓咱們更詳細的瞭解一下每種報告模式。

靜默報告模式是一種不須要用戶作任何操做的模式。不會有任何錯誤相關的信息顯示給用戶。用戶也不會知道任何關於錯誤的狀況,除非有一些可視化的處理程序顯示了錯誤信息(例如,Toast 處理程序)。當你不想詢問用戶以獲取處理錯誤的權限時,你可使用此報告模式。

示例代碼:

CatcherOptions(SilentReportMode(), [ConsoleHandler()]);複製代碼

通知報告模式顯示用戶本地通知。一旦用戶點擊了它,報告將被配置的處理程序接受並處理。

示例代碼:

CatcherOptions(NotificationReportMode(), [ConsoleHandler()]);複製代碼

對話框報告模式會向用戶顯示一個對話框。對話框中有兩個按鈕:「贊成」和「取消」。點擊「贊成」按鈕將推送錯誤日誌處處理程序,點擊「取消」將解除報告。

CatcherOptions(
    DialogReportMode(
        titleText: "Title",
        descriptionText: "Description",
        acceptText: "Accept",
        cancelText: "Cancel"),
    [ConsoleHandler()]);複製代碼


頁面報告模式顯示一個新的全屏頁面,其中包括錯誤描述信息、棧跟蹤、和兩個按鈕。

CatcherOptions(
    PageReportMode(
        titleText: "Title",
        descriptionText: "Description",
        acceptText: "Accept",
        cancelText: "Cancel",
        showStackTrace: false),
    [ConsoleHandler()]);複製代碼

對話框報告模式和頁面報告模式須要在應用中配置 navigation key 。這是很是簡單的,你只須要在你的 MaterialApp widget 中增長一行代碼。

@override  Widget build(BuildContext context) {
    return MaterialApp(
      //********************************************
      navigatorKey: Catcher.navigatorKey,
      //********************************************
      home: Scaffold(
          appBar: AppBar(
            title: const Text('Plugin example app'),
          ),
          body: ChildWidget()),
    );
  }複製代碼

報告模式有多個配置選項。你能夠在這裏找到全部的配置項。



報告模式(從上到下依次爲):通知模式,對話框模式,頁面模式。靜默模式沒有任何可視界面

處理程序

在報告流程中,處理程序是最後一個環節。它們消費報告並對報告作一些處理。在每個配置組中,你能夠設置多個處理程序,例如 Console 處理程序、文件處理程序。讓咱們更進一步地瞭解每一種 處理程序。

Console 處理程序 是一個基本的處理程序。它會打印格式化的報告到控制檯中。你能夠配置 Console 處理程序打印或不打印報告的某些部分。

示例代碼:

CatcherOptions(DialogReportMode(), [
  ConsoleHandler(
      enableApplicationParameters: true,
      enableCustomParameters: true,
      enableStackTrace: true,
      enableDeviceParameters: true)
]);複製代碼


控制檯處理程序


文件處理程序把錯誤日誌保存到用戶的設備中。你只需傳入保存文件的路徑。

示例代碼:

Directory externalDir = await getExternalStorageDirectory();

String path = externalDir.path.toString() + "/log.txt";

CatcherOptions debugOptions = CatcherOptions(DialogReportMode(),
 [FileHandler(File(path))]);

CatcherOptions releaseOptions = CatcherOptions(DialogReportMode(),
 [FileHandler(File(path))]);

Catcher(MyApp(), debugConfig: debugOptions, releaseConfig:
 releaseOptions);複製代碼


文件處理程序保存報告到文件中

Http 處理程序容許用戶經過 Http 請求發送數據到服務器。目前,只支持 Http POST 方式的請求。你能夠在請求中添加自定義的 header。

示例代碼:

CatcherOptions(DialogReportMode(), [
  HttpHandler(HttpRequestType.post,
 Uri.parse("http://logs.server.com"),
      headers: {"header": "value"},
 requestTimeout: 4000, printLogs: false)
]);複製代碼

有一個用 Java 實現的簡單的 Catcher 報告服務端。你能夠在這裏找到。


後端服務器顯示了收集到的報告。

自動郵件處理程序增長了發郵件功能。此處理程序自動發送郵件到指定的郵箱。你須要設置好用於發送郵件的用戶名和密碼,所以,我推薦僅在開發階段使用此處理方式。

示例代碼:

CatcherOptions(DialogReportMode(),
    [EmailAutoHandler(
        "smtp.gmail.com", 587,
        "somefakeemail@gmail.com",
        "Catcher", 
       "FakePassword", ["myemail@gmail.com"])
    ]);複製代碼


從自動郵件處理程序收到的郵件。

手動郵件處理程序與自動郵件處理程序不一樣。此處理程序建立郵件並打開默認的郵件應用。用戶須要完成發送郵件的操做。你無需指定發件人的用戶名和密碼,由於用戶會將使用他本身的郵箱做爲發件人,因此,在發佈階段使用此方式是安全的。

示例代碼:

CatcherOptions(DialogReportMode(), [
  EmailManualHandler(["email1@email.com", "email2@email.com"],
      enableDeviceParameters: true,
      enableStackTrace: true,
      enableCustomParameters: true,
      enableApplicationParameters: true,
      sendHtml: true,
      emailTitle: "Sample Title",
      emailHeader: "Sample Header",
      printLogs: true)
]);複製代碼


郵件處理程序生成的示例郵件

Toast 處理程序是最後一種處理程序。它在用戶屏幕上顯示 toast 。當你只須要給用戶顯示簡短的信息時,這很是有用。

示例:

CatcherOptions(DialogReportMode(), [
  ToastHandler(
      gravity: ToastHandlerGravity.bottom,
      length: ToastHandlerLength.long,
      backgroundColor: Colors.red,
      textColor: Colors.white,
      textSize: 12.0,
      customMessage: "We are sorry but unexpected error occured.")
]);複製代碼


Toast 處理程序顯示帶有錯誤信息的 Toast

全部處理程序和它們的配置選項的介紹能夠在這裏找到。

你甚至能夠定義你本身的處理程序!只須要建立一個繼承自 ReportHandler 的類:

import 'package:catcher/catcher_plugin.dart';

class MyHandler extends ReportHandler{
  @override  Future<bool> handle(Report error) async{
    //my implementation
    return true;
  }  
}複製代碼

小結

Catcher 是一個新的插件,可是很強大。此插件還在開發中,但你能夠在你的項目中使用了。在你的項目中實現它很是的簡單直接,值得一試!

你能夠在 GitHub 中自由地報告問題或提供反饋,也歡迎你向 Catcher 增長新的功能。歡迎自由地爲這個項目作貢獻!

項目 GitHub 地址:github.com/jhomlala/ca…

謝謝閱讀!

相關文章
相關標籤/搜索