Управление ошибками при публикации в Flutter - PullRequest
0 голосов
/ 28 февраля 2020

Я сделал заявление для компании, в которой я работаю, приложение работает и решило некоторые проблемы, но код беспорядок, так как я не официальный программист, и это мое самое первое приложение. Теперь я пытаюсь улучшить код.

Проблема здесь в том, что я не знаю, как проверить, была ли публикация http успешной.

В приведенном ниже коде вы можете видеть, что я сделал некоторая обработка ошибок, но она не работает должным образом. Например, если приложение не получит сообщение «ОК» от сервера, оно вернет ошибку, но если inte rnet не работает, оно не вернет ошибку, потому что оно будет пытаться отправить сообщение навсегда. Я хотел бы всегда проверять, была ли публикация успешной, и уведомлять пользователя или показывать ошибку после некоторого времени попытки (например, 2 секунды, я не знаю), каков наилучший способ решить эту проблему?

Любой другие советы по улучшению кода приветствуются.

    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();
                                      }),
                                ]);
                          });
                    }
                  })
            ],
          );
        },
      );
    }
  }```

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

, но если inte rnet не работает, он не вернет ошибку, потому что будет пытаться отправить сообщение навсегда.

Чтобы решить, что вы хотите сделать, это добавьте тайм-аут к вашим вызовам 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');
}

Любые другие советы по улучшению кода приветствуются.

Я предлагаю сделать отдельные файлы дротиков с методами для разных частей кода, который будет повторяться в вашем приложении.

1) Создайте что-то вроде http_handler.dart, которое будет иметь асин c методы httpPost и httpGet. Пример:

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) Создайте что-то вроде verify_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);
                },
              )
            ],
          );
        },
      );
    }

Затем, когда вам потребуется, чтобы ваш пользователь подтвердил или отменил действие, вы можете использовать его следующим образом:

  ConfirmAction action = await ConfirmDialog(context, "Dialog Title", "Dialog Content");
  if (action == ConfirmAction.ACCEPT) {
     //do something
  }
0 голосов
/ 28 февраля 2020

Я создал пример проекта для базового проекта флаттера для такой вещи, его легко обслуживаемая и чистая копия кода, вот ссылка

https://github.com/SouravKumarPandit/flutter_base_project

В случае, если вам не нужна вся структура проекта. Вы можете использовать этот пакет для получения чистого и структурированного кода

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...