简体   繁体   English

在 Flutter 中管理帖子中的错误

[英]Managing errors on post in Flutter

I made an application for the company that i work, the app its working and solved some problems, but the code is a mess, since i'm not a official programmer and this is my very first application.我为我工作的公司制作了一个应用程序,该应用程序可以运行并解决了一些问题,但是代码一团糟,因为我不是官方程序员,这是我的第一个应用程序。 Now i'm trying to improve the code.现在我正在尝试改进代码。

The problem here is that i dont know how to check if the http post was successful.这里的问题是我不知道如何检查 http 帖子是否成功。

In the code below you can see that i made some error treatment but its not working properly.在下面的代码中,您可以看到我进行了一些错误处理,但无法正常工作。 For example, if the app doesnt receive the "ok" message from the server it will return a error, but if the internet isnt working it will not return the error because it will be trying forever to send the post.例如,如果应用程序没有收到来自服务器的“ok”消息,它将返回一个错误,但如果互联网不工作,它将不会返回错误,因为它将永远尝试发送帖子。 I would like to always check if the post was successfull and notify the user, or show a error after a time of trying (like 2 seconds, i dont know), whats the best way to solve this?我想始终检查帖子是否成功并通知用户,或者在尝试一段时间后显示错误(例如 2 秒,我不知道),解决此问题的最佳方法是什么?

Any other tips to improve the code are welcome.欢迎任何其他改进代码的提示。

    if ((_usuarioController.text.isEmpty) ||
        (_placaController.text.isEmpty) ||
        (_boxController.text.isEmpty) ||
        (dropdownValue1 == "Vehicle type")) {
      Toast.show(
        "\n  Complete all fields  \n",
        context,
        duration: Toast.LENGTH_LONG,
        gravity: Toast.CENTER,
        backgroundRadius: 5.0,
      );
    } else if (_pecasList.length < 1) {
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
                title: new Text("Empty List"),
                actions: <Widget>[
                  new FlatButton(
                      child: new Text("Close"),
                      onPressed: () {
                        Navigator.of(context).pop();
                      }),
                ]);
          });
    } else {
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: new Text("Send the items?"),
            actions: <Widget>[
              new FlatButton(
                  child: new Text("Close"),
                  onPressed: () {
                    Navigator.of(context).pop();
                  }),
              new FlatButton(
                  child: new Text("Send"),

                  onPressed: () async {
                    Map<String, dynamic> newDados = Map(); 
                    newDados["usuario"] = _usuarioController.text.trimLeft();
                    newDados["placa"] = _placaController.text.trimLeft();
                    newDados["box"] = _boxController.text.trimLeft();
                    newDados["tipo_veiculo"] = dropdownValue1;
                    _dadosList.add(newDados);
                    print(_pecasList + _dadosList);

                    Map<String, String> headers = new Map<String, String>();
                    headers["Content-type"] = "application/json";
                    headers["Accept"] = "application/json";
                    //String str = '{"take":55, "skip":"0"}';
                    final resp = await http.post('http://' + ipServidor,
                        body: jsonEncode(_dadosList +
                            _pecasList), //+ jsonEncode(_pecasList),
                        headers: headers);

                    print(resp.statusCode);

                    _dadosList
                        .clear(); //Cleans the list
                    print(resp.body);
                    if (resp.statusCode == 200) {
                      if (resp.body == "ok") {
                        setState(() {
                          print(_pecasList);
                          _pecasList.clear();
                          _placaController.clear();
                          _boxController.clear();
                          dropdownValue1 = "Vehicle type";

                          Navigator.of(context).pop();
                        });
                      } else {
                        showDialog(
                            context: context,
                            builder: (BuildContext context) {
                              return AlertDialog(
                                  title: new Text(
                                      "Error"),
                                  actions: <Widget>[
                                    new FlatButton(
                                        child: new Text("Close"),
                                        onPressed: () {
                                          Navigator.of(context).pop();
                                          Navigator.of(context).pop();
                                        }),
                                  ]);
                            });
                      }
                    } else {
                      print("communication error");
                      Navigator.of(context).pop();
                      showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                                title: new Text("communication error"),
                                actions: <Widget>[
                                  new FlatButton(
                                      child: new Text("Close"),
                                      onPressed: () {
                                        Navigator.of(context).pop();
                                      }),
                                ]);
                          });
                    }
                  })
            ],
          );
        },
      );
    }
  }```

but if the internet isnt working it will not return the error because it will be trying forever to send the post.但如果互联网不工作,它不会返回错误,因为它将永远尝试发送帖子。

To solve that what you wanna do is to add timeout to your http calls.要解决这个问题,您要做的是在 http 调用中添加超时。

int timeout = 10;
try {
  http.Response response = await http.post('http://' + ipServidor,
      headers: headers,
      body: jsonEncode(_dadosList + _pecasList), encoding: utf8).
      timeout(Duration(seconds: timeout));
  if (response.statusCode == 200) {
    // do something
  } else {
    // handle it
  }
} on TimeoutException catch (e) {
  print('Timeout Error: $e');
} on SocketException catch (e) {
  print('Socket Error: $e');
} on Error catch (e) {
  print('General Error: $e');
}

Any other tips to improve the code are welcome.欢迎任何其他改进代码的提示。

I suggest making a separate dart files with methods for different parts of the code that will be recurring in your app.我建议制作一个单独的 dart 文件,其中包含将在您的应用程序中重复出现的代码的不同部分的方法。

1) Create something like http_handler.dart that will have async methods httpPost and httpGet. 1) 创建类似 http_handler.dart 的东西,它将具有异步方法 httpPost 和 httpGet。 Example:例子:

httpGet(String url, int attempts, int timeout) async {
  var parsedJson;
  bool success = false;
  int attempt=0;
  while(!success && attempt<attempts) {
    attempt++;
    // your httpGet try catch block
    // inside of it -> if response == 200 then success = true
    // also parse your json here
    if(!success) {
      sleep(const Duration(milliseconds: 500)); //sleep a bit between attempts
    }
  } 
  return parsedJson;
}

2) Create something like confirm_dialog.dart 2)创建类似confirm_dialog.dart的东西

import 'package:flutter/material.dart';

enum ConfirmAction { CANCEL, ACCEPT }

    Future<ConfirmAction> ConfirmDialog(BuildContext context, String title, String content) async {
      return showDialog<ConfirmAction>(
        context: context,
        barrierDismissible: false, // user must tap on a button to close the dialog!
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text(title),
            content: Text(content),
            actions: <Widget>[
              FlatButton(
                child: Text("NO"),
                onPressed: () {
                  Navigator.of(context).pop(ConfirmAction.CANCEL);
                },
              ),
              FlatButton(
                child: Text("YES"),
                onPressed: () {
                  Navigator.of(context).pop(ConfirmAction.ACCEPT);
                },
              )
            ],
          );
        },
      );
    }

Then when you need your user to confirm or cancel an action you can use it like this:然后,当您需要用户确认或取消操作时,您可以像这样使用它:

  ConfirmAction action = await ConfirmDialog(context, "Dialog Title", "Dialog Content");
  if (action == ConfirmAction.ACCEPT) {
     //do something
  }

I have created sample project for flutter base project to such thing , its highly maintainable and clean copy the code here is the link我已经为这样的东西创建了颤振基础项目的示例项目,它的高度可维护性和干净的复制代码在这里是链接

https://github.com/SouravKumarPandit/flutter_base_project https://github.com/SouravKumarPandit/flutter_base_project

In case if you don't want the whole project structure.you can use this package for having clean and structured code如果你不想要整个项目结构。你可以使用这个来获得干净和结构化的代码

https://pub.dev/packages/mvvm_flutter#-installing-tab- https://pub.dev/packages/mvvm_flutter#-installing-tab-

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM