Flutter自定义错误处理插件custom_error的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter自定义错误处理插件custom_error的使用

custom_error 是一个用于简化Flutter应用程序中错误管理的包。它提供了一个灵活的 CustomError 类,允许你轻松创建、存储和访问自定义错误实例。以下是关于如何使用该插件的详细介绍和完整示例。

主要功能

  • 自定义错误管理:创建和管理带有错误代码和消息的自定义错误对象。
  • 灵活的错误存储:使用列表存储多个错误。
  • 错误检索:通过getter方法轻松访问单个错误详情。
  • 错误状态检查:使用 hasAnError() 方法检查是否存在错误。
  • 类型检查:使用 isAnError() 方法确定对象是否是 CustomError 的实例。
  • 显示对话框:当发生错误时,显示带有自定义标题、消息和操作的对话框。
  • 显示SnackBar:根据错误条件显示带有自定义背景和行为的SnackBar。
  • 错误日志记录:将错误报告发送到远程服务器/电子邮件/日志以进行进一步分析,帮助识别和修复生产中的问题。
  • 彩色控制台消息:根据错误级别显示不同颜色的消息。

安装

要在你的Flutter项目中使用 custom_error 包,请在 pubspec.yaml 文件中添加依赖项:

dependencies:
  custom_error: ^latest_version

^latest_version 替换为你想要使用的具体版本,然后运行 flutter pub get 来获取并安装该包。

使用示例

以下是一个完整的示例,展示了如何在Flutter应用程序中使用 custom_error 包。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:custom_error/custom_error_manager.dart';
import 'package:custom_error/custom_error.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Error Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Custom Error Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _textController = TextEditingController();
  String _inputText = '';
  List<String> names = ['Yung', 'Cet', 'Cedric'];

  void _validate() {
    CustomError error = CustomError();
    String inputName = _textController.text;

    if (!names.contains(inputName)) {
      error.setError(-1, 'Name not found.');
    }

    setState(() {
      _inputText = (error.hasAnError())
          ? 'Error: ${error.getError()} - Code: ${error.getErrorCode()}'
          : _textController.text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _textController,
              decoration: InputDecoration(labelText: 'Search Name'),
            ),
            SizedBox(height: 16.0),
            Row(
              children: [
                ElevatedButton(
                  onPressed: _validate,
                  child: Text('Validate'),
                ),
                SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () {
                    CustomError customError = CustomError();
                    customError.addError(100, 'This is error 100');
                    customError.addError(101, 'This is error 101');
                    customError.addError(102, 'This is error 102');

                    print('Last error: ${customError.getLatestError()}');
                    print('findErrorByCode 101: ${customError.findErrorByCode(101)}');

                    setState(() {
                      _inputText = '${customError.getAllErrors()}';
                    });
                  },
                  child: Text('Show Multiple Errors'),
                ),
                SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () {
                    CustomError customError = CustomError();
                    customError.setError(-1, 'Showing Error Dialog');

                    // 添加对话框按钮
                    final actions = <Widget>[
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('OK'),
                      ),
                      TextButton(
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                        child: Text('Cancel'),
                      )
                    ];

                    CustomErrorManager.showDialogIfError(
                        context,
                        customError,
                        'Error Dialog',
                        null, // 当设置为null时,使用 customError.getError()
                        actions);
                  },
                  child: Text('Show Error Dialog'),
                ),
                SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () {
                    CustomError customError = CustomError();
                    customError.setError(-1, 'Showing Error SnackBar');
                    CustomErrorManager.showSnackBarIfError(
                        context, customError,
                        behavior: SnackBarBehavior.fixed);
                  },
                  child: Text('Show Error SnackBar'),
                ),
                SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () {
                    CustomErrorManager customErrorManager = CustomErrorManager();
                    // 记录警告信息
                    customErrorManager.log(w: 'Warning Message');

                    // 记录错误信息
                    customErrorManager.log(e: 'Error Message');

                    // 记录信息
                    customErrorManager.log(i: 'Info Message');

                    // 记录调试信息
                    customErrorManager.log(d: 'Debug Message');

                    // 记录致命信息
                    customErrorManager.log(f: 'Fatal Message');

                    // 记录跟踪信息
                    customErrorManager.log(t: 'Trace Message');

                    setState(() {
                      _inputText = 'check console for output';
                    });
                  },
                  child: Text('Log Error'),
                ),
                SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () async {
                    // 将错误发送到服务器
                    // final data = {}; // 要发送的数据
                    // CustomErrorManager customErrorManager = CustomErrorManager();
                    // await customErrorManager.sendToServer(
                    //   url: 'url', // 端点
                    //   methodType: 'post', // 请求方法(仅支持POST和GET)
                    //   headers: <String, String>{    // 请求头
                    //     'Content-Type': 'application/json',
                    //   },
                    //   body: jsonEncode(data) // 编码数据
                    // );

                    // 通过CustomManager发送错误日志
                    CustomErrorManager customErrorManager = CustomErrorManager();
                    await customErrorManager.emailLog(
                        message: 'An error has occurred',
                        recipient: 'recipient@example.com', // 可以通过逗号分隔添加多个收件人
                        appTitle: 'Custom Error Demo');

                    setState(() {
                      _inputText = 'check console for output';
                    });
                  },
                  child: Text('Email Log'),
                ),
              ],
            ),
            SizedBox(height: 16.0),
            Align(
              alignment: Alignment.centerLeft,
              child: Text('Response: $_inputText'),
            ),
          ],
        ),
      ),
    );
  }
}

CustomErrorManager

CustomErrorManager 类用于基于 CustomError 实例管理对话框。它提供了显示对话框和SnackBar的方法,并且可以记录不同级别的日志消息。

显示对话框

showDialogIfError 方法会在 CustomError 对象中存在错误时显示一个对话框。你可以提供标题、消息和操作按钮来自定义对话框。

Custom Error Dialog

CustomError customError = CustomError();
customError.setError(-1, 'Showing Error Dialog');

// 添加对话框按钮
final actions = <Widget>[
  TextButton(
    onPressed: () {
      Navigator.of(context).pop();
    },
    child: Text('OK'),
  ),
  TextButton(
    onPressed: () {
      Navigator.of(context).pop();
    },
    child: Text('Cancel'),
  )
];

CustomErrorManager.showDialogIfError(
    context, 
    customError, 
    'Error Dialog', 
    null, // 当设置为null时,使用 customError.getError()
    actions
);
显示SnackBar

showSnackBarIfError 方法会在 CustomError 对象中存在错误时显示一个SnackBar。你可以自定义SnackBar的背景颜色和行为。

Custom Error SnackBar

CustomError customError = CustomError();
customError.setError(-1, 'Showing Error SnackBar');
CustomErrorManager.showSnackBarIfError(
    context, customError,
    behavior: SnackBarBehavior.fixed);
日志记录

log 方法用于记录不同级别的日志消息,包括错误、警告、信息、调试、致命和跟踪信息。只有非空的消息才会被记录。

CustomErrorManager customErrorManager = CustomErrorManager();
// 记录警告信息
customErrorManager.log(w: 'Warning Message');

// 记录错误信息
customErrorManager.log(e: 'Error Message');

// 记录信息
customErrorManager.log(i: 'Info Message');

// 记录调试信息
customErrorManager.log(d: 'Debug Message');

// 记录致命信息
customErrorManager.log(f: 'Fatal Message');

// 记录跟踪信息
customErrorManager.log(t: 'Trace Message');
发送错误报告到服务器

sendToServer 方法将错误报告发送到指定的URL,使用指定的HTTP方法。你可以包含可选的参数,如请求头、请求体和编码。

final data = {}; // 要发送的数据
CustomErrorManager customErrorManager = CustomErrorManager();
await customErrorManager.sendToServer(
   url: 'url', // 端点
   methodType: 'post', // 请求方法(仅支持POST和GET)
   headers: <String, String>{    // 请求头
     'Content-Type': 'application/json',
   },
   body: jsonEncode(data) // 编码数据
 );
通过电子邮件发送日志

emailLog 方法通过电子邮件发送日志消息。它包括日志消息、收件人的电子邮件地址和应用程序标题作为邮件主题。

CustomErrorManager customErrorManager = CustomErrorManager();
await customErrorManager.emailLog(
  message: 'An error has occurred',
  recipient: 'recipient@example.com', // 可以通过逗号分隔添加多个收件人
  appTitle: 'Custom Error Demo'
);

示例用法

以下是一些使用 custom_error 包的示例:

// 记录错误信息
CustomErrorManager.log(e: 'This is an error message');

// 如果存在错误,显示对话框
CustomError customError = CustomError();
customError.setError(-1, 'An error occurred.');
CustomErrorManager.showDialogIfError(context, customError, 'Error', 'An error occurred', null);

// 如果存在错误,显示SnackBar
CustomErrorManager.showSnackBarIfError(context, customError, backgroundColor: Colors.red);

// 将错误报告发送到服务器
CustomErrorManager.sendToServer(url: 'https://example.com/report', methodType: 'POST', body: 'Report data');

// 通过电子邮件发送日志
CustomErrorManager.emailLog(message: 'Error message', recipient: 'recipient@example.com', appTitle: 'My App');

更多关于Flutter自定义错误处理插件custom_error的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义错误处理插件custom_error的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用自定义错误处理插件custom_error的示例代码。假设custom_error插件已经发布在pub.dev上,并且它提供了一些基本的错误捕捉和处理功能。

首先,你需要在pubspec.yaml文件中添加该插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  custom_error: ^latest_version  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来,在你的Flutter应用中,你可以按照以下步骤来设置和使用custom_error插件进行自定义错误处理。

1. 初始化插件

在你的主文件(通常是main.dart)中,初始化custom_error插件。

import 'package:flutter/material.dart';
import 'package:custom_error/custom_error.dart';

void main() {
  // 初始化插件
  CustomError.init(onError: handleGlobalError);

  runApp(MyApp());
}

void handleGlobalError(CustomError error) {
  // 这里可以处理全局错误,比如打印日志、显示对话框等
  print('Caught an error: ${error.message}');
  // 例如,显示一个简单的Snackbar(注意:这需要在MaterialApp的上下文中)
  // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error.message)));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

注意:由于ScaffoldMessenger.of(context).showSnackBar需要一个BuildContext,而在全局错误处理函数中通常没有可用的上下文,因此你可能需要设计一种机制来在UI层触发Snackbar显示,比如通过事件总线(Event Bus)或者状态管理库(如Provider、Riverpod等)。

2. 在具体组件中使用错误捕捉

假设你有一个按钮,点击后会触发一个可能会抛出异常的函数:

import 'package:flutter/material.dart';
import 'package:custom_error/custom_error.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _handleError(Object error, StackTrace stackTrace) {
    // 将错误封装为CustomError对象并抛出
    CustomError customError = CustomError(
      message: error.toString(),
      stackTrace: stackTrace.toString(),
    );
    CustomError.reportError(customError);
  }

  void _riskyOperation() {
    try {
      // 这里是一些可能会抛出异常的操作
      throw Exception('Something went wrong!');
    } catch (e, s) {
      _handleError(e, s);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _riskyOperation,
          child: Text('Do Risky Operation'),
        ),
      ),
    );
  }
}

在这个示例中,_riskyOperation函数可能会抛出一个异常。我们通过try-catch块捕捉这个异常,并调用_handleError函数来处理它。在_handleError函数中,我们将异常信息封装成一个CustomError对象,并通过CustomError.reportError方法报告这个错误。

3. 处理报告的错误(可选)

如果你希望在全局层面处理报告的错误,你可以在CustomError.init时提供的onError回调函数中实现逻辑。这个回调函数会在CustomError.reportError被调用时触发。

注意事项

  • 实际的custom_error插件的API可能会有所不同,请查阅其官方文档以获取准确的使用方法和API。
  • 错误处理是一个复杂的话题,你可能需要根据应用的具体需求来设计更复杂的错误处理机制。

希望这个示例能帮助你理解如何在Flutter中使用自定义错误处理插件。如果有任何进一步的问题,请随时提问!

回到顶部