简体   繁体   中英

Dart: Exit of a async method without any trace

The following method will be reached. But none of the 3 logging statements will be fired.


    void readAndExecute(String sql, List parameters,
        CallbackOnSingleRow onSingleRow) async {
     _lastResults = null;
     await _dbConnection.query(sql, parameters).then((Results result) {
      _logger.log('something found', LEVEL_FINE);
      for (var row in result) {
        _lastResults ??= result;
        onSingleRow(row);
      }
     }).catchError((error) {
      _logger.error('read failed: $error\n$sql');
      throw DbException('readAndExecute()', sql, parameters, error.toString());
     });
     _logger.log('end of readAndExecute() reached', LEVEL_FINE);
    }

  • _dbConnection is a valid MySqlConnection instance (successful login)
  • sql is a valid SQL statement (tested with a DB tool):
  • sql: select * from users where user_id >?;
  • parameters: [0]
  • The logging of the packet mysql1 is activated, the output is:
FINE: 2020-05-10 11:33:40.060170: start handler Instance of 'PrepareHandler'
FINE: 2020-05-10 11:33:40.060748: sendBuffer header
FINE: 2020-05-10 11:33:40.060938: sending header, packet 0
FINE: 2020-05-10 11:33:40.061021: writeBuffer length=4
FINE: 2020-05-10 11:33:40.061091: _writeBuffer offset=0
FINE: 2020-05-10 11:33:40.061278: Wrote 4 bytes
FINE: 2020-05-10 11:33:40.061438: 
38 00 00 00                8···    

I'm afraid I didn't understand something about the "async-await" concept.

After answer 1 the code is changed to:


    try {
      _lastResults = await _dbConnection.query(sql, parameters);
      _logger.log('result reached', LEVEL_FINE);
      for (var row in _lastResults) {
        onSingleRow(row);
      }
    } catch (exc) {
      _logger.error('readAndExecute(): $exc\n$sql');
    }

But the problem remains: the 2 loggings will not be reached.

Here I simplified both versions of the code that you provided:

Future readAndExecute() async {
  print(1);
  await Future.delayed(Duration(seconds: 1)).then((i) {
    print(2);
  }).catchError((error) {
    print(3);
    throw "thrown";
  });
  print(4);
}
// prints:
// 1
// 2
// 4

Future secondTry() async {
  try {
    await Future.delayed(Duration(seconds: 1));
    print(1);
  } catch (exc) {
    print(2);
  }
}

// prints:
// 1

Talking about the second one, you should be seeing result reached ( 1 in my example), if _dbConnection.query(sql, parameters) is indeed completing.

I would really make sure the functions are actually called. Put a log before anything else in the functions and see if you see it in your logs. So:

    _logger.log('CALLED INDEED', LEVEL_FINE);
    try {
      _lastResults = await _dbConnection.query(sql, parameters);
      _logger.log('result reached', LEVEL_FINE);
      for (var row in _lastResults) {
        onSingleRow(row);
      }
    } catch (exc) {
      _logger.error('readAndExecute(): $exc\n$sql');
    }

Future secondTry() async {
  print(0);
  try {
    await Future.delayed(Duration(seconds: 1));
    print(1);
  } catch (exc) {
    print(2);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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