Flutter错误处理与结果返回插件error_or_result的使用

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

Flutter错误处理与结果返回插件 error_or_result 的使用

error_or_result 是一个用于优雅地处理错误(如领域错误)的库,通过将返回的结果作为正常程序流程的一部分来处理,从而减少抛出异常的数量。该库受到了 C# 版本 的启发。

示例代码

下面是一个完整的示例,展示了如何在 Flutter 应用中使用 error_or_result 插件来处理错误和返回结果。

定义实体类

import 'package:error_or_result/error_or_result.dart';

class Employee {
  int id;
  String name;
  int? managerId;

  Employee({
    required this.id,
    required this.name,
    this.managerId,
  });
}

class Company {
  final String name;
  List<Employee> employees;

  Company({required this.name, required this.employees});
}

定义错误类型

class CompanyDomainErrors {
  static ErrorResult notHeadOfCompany = ErrorResult.validation(
      code: "CompanyError.NotHeadOfCompany",
      description: "The employee is not the head of the company.");
  static ErrorResult isNotRegisteredEmployee = ErrorResult.notFound(
      code: "CompanyError.DoesntExist",
      description: "The employee is not registered in the company.");
}

创建服务类

class CompanyDomainService {
  static ErrorOr<Employee> getCompanyEmployeeById(int employeeId) {
    var doesEmployeeExist = carCompany.employees.map((e) => e.id).toList().remove(employeeId);
    if (doesEmployeeExist != null) {
      Employee employee = carCompany.employees.firstWhere((employee) => employee.id == employeeId);
      return ErrorOr.fromResult(employee);
    }
    return ErrorOr.fromErrors([CompanyDomainErrors.isNotRegisteredEmployee]);
  }

  static ErrorOr<bool> isHeadOfCompany(Employee employee) {
    if (employee.managerId == null && carCompany.employees.contains(employee)) {
      return ErrorOr.fromResult(true);
    }
    return ErrorOr.fromError(CompanyDomainErrors.notHeadOfCompany);
  }
}

初始化公司数据

var ali = Employee(id: 1, name: "Ali");
var john = Employee(id: 2, name: "John", managerId: 1);
var alex = Employee(id: 3, name: "Alex", managerId: 2);
var jane = Employee(id: 4, name: "Jane", managerId: 3);
var carCompany = Company(name: "SmartX Cars Dealership", employees: [ali, john, alex, jane]);

使用 ErrorOr<T> 类处理结果

void main() {
  // Example for ErrorOr<T> class approach
  ErrorOr<bool> isHeadOFCompanyResult = CompanyDomainService.isHeadOfCompany(john);
  if (isHeadOFCompanyResult.isError) {
    print(isHeadOFCompanyResult.firstError.description);
  } else {
    print(isHeadOFCompanyResult.result);
  }

  ErrorOr<Employee> employeeResult = CompanyDomainService.getCompanyEmployeeById(2);
  if (employeeResult.isError) {
    print(employeeResult.firstError.code);
  } else {
    print(employeeResult.result.name);
  }
}

使用 ErrorOrValue<T> 类处理结果

class CompanyDomainErrorOrValueErrors {
  static VFailure notHeadOfCompany = VFailure.validation(
      code: "CompanyError.NotHeadOfCompany",
      description: "The employee is not the head of the company.");
  static VFailure isNotRegisteredEmployee = VFailure.notFound(
      code: "CompanyError.DoesntExist",
      description: "The employee is not registered in the company.");
}

class CompanyDomainServiceErrorOrValue {
  static ErrorOrValue<Employee> getCompanyEmployeeById(int employeeId) {
    var doesEmployeeExist = carCompany.employees.map((e) => e.id).toList().remove(employeeId);
    if (doesEmployeeExist != null) {
      Employee employee = carCompany.employees.firstWhere((employee) => employee.id == employeeId);
      return ErrorOrValue.fromResult(employee);
    }
    return ErrorOrValue.fromErrors([CompanyDomainErrorOrValueErrors.isNotRegisteredEmployee]);
  }

  static ErrorOrValue<bool> isHeadOfCompany(Employee employee) {
    if (employee.managerId == null && carCompany.employees.contains(employee)) {
      return ErrorOrValue.fromResult(true);
    }
    return ErrorOrValue.fromErrors([CompanyDomainErrorOrValueErrors.notHeadOfCompany]);
  }
}

void main() {
  // Example for ErrorOrValue<T> class approach
  ErrorOrValue<bool> isBossOfCompanyResult = CompanyDomainServiceErrorOrValue.isHeadOfCompany(john);
  if (isBossOfCompanyResult.isError) {
    print(isBossOfCompanyResult.errors.first.description);
  } else {
    print(isBossOfCompanyResult.result);
  }

  ErrorOrValue<Employee> eResult = CompanyDomainServiceErrorOrValue.getCompanyEmployeeById(2);
  if (eResult.isError) {
    print(eResult.errors.first.code);
  } else {
    print(eResult.result.name);
  }
}

更多关于Flutter错误处理与结果返回插件error_or_result的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter错误处理与结果返回插件error_or_result的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,error_or_result 是一个用于错误处理和结果返回的实用插件。它提供了一种简洁的方式来处理异步操作的成功或失败情况,而不是依赖于传统的回调或 Future。以下是如何在Flutter项目中使用 error_or_result 插件的一个示例代码案例。

首先,确保你的 pubspec.yaml 文件中已经添加了 error_or_result 依赖:

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

然后,运行 flutter pub get 来安装依赖。

接下来,我们编写一个示例,展示如何使用 ErrorOrResult 来处理异步操作。假设我们有一个模拟的API调用,它可能成功返回一个字符串,也可能失败并返回一个错误。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ErrorOrResult Example'),
        ),
        body: Center(
          child: ErrorOrResultExample(),
        ),
      ),
    );
  }
}

class ErrorOrResultExample extends StatefulWidget {
  @override
  _ErrorOrResultExampleState createState() => _ErrorOrResultExampleState();
}

class _ErrorOrResultExampleState extends State<ErrorOrResultExample> {
  final _formKey = GlobalKey<FormState>();
  String? _result;
  String? _errorMessage;

  void _submitForm() async {
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();
      
      // 模拟API调用
      final result = await performAsyncOperation();

      // 处理结果
      result.when(
        data: (data) {
          setState(() {
            _result = data;
            _errorMessage = null;
          });
        },
        error: (error, stackTrace) {
          setState(() {
            _result = null;
            _errorMessage = error.toString();
          });
        },
      );
    }
  }

  // 模拟的异步操作,返回ErrorOrResult<String>
  Future<ErrorOrResult<String>> performAsyncOperation() async {
    // 模拟延迟
    await Future.delayed(Duration(seconds: 2));

    // 随机返回成功或失败
    bool success = Random().nextBool();
    if (success) {
      return ErrorOrResult.data('Operation successful!');
    } else {
      return ErrorOrResult.error(Exception('Operation failed.'));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            onPressed: _submitForm,
            child: Text('Perform Async Operation'),
          ),
          SizedBox(height: 20),
          if (_result != null)
            Text(
              'Result: $_result',
              style: TextStyle(fontSize: 20, color: Colors.green),
            ),
          if (_errorMessage != null)
            Text(
              'Error: $_errorMessage',
              style: TextStyle(fontSize: 20, color: Colors.red),
            ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的表单,包含一个按钮。点击按钮时,会触发一个模拟的异步操作 performAsyncOperation,该操作返回一个 ErrorOrResult<String> 对象。根据操作的成功或失败,我们使用 when 方法来处理数据或错误,并更新UI。

这个示例展示了如何使用 error_or_result 插件来简化错误处理和结果返回的逻辑,使代码更加清晰和易于维护。

回到顶部