2
votes

I'm trying to caught an error from a completer.

Here, my method to decode a token

  Future<Map> decode(String token) {
    var completer = new Completer();

    new Future(() {
      List<String> parts = token.split(".");
      Map result = {};

      try {
        result["header"] = JSON.decode(new String.fromCharCodes(crypto.CryptoUtils.base64StringToBytes(parts[0])));
        result["payload"] = JSON.decode(new String.fromCharCodes(crypto.CryptoUtils.base64StringToBytes(parts[1])));
      } catch(e) {
        completer.completeError("Bad token");
        return;
      }
      encode(result["payload"]).then((v_token) {
        if (v_token == token) {
          completer.complete(result);
        } else {
          completer.completeError("Bad signature");
        }
      });
    });
    return completer.future;
  }
}

The call:

  var test = new JsonWebToken("topsecret");

  test.encode({"field": "ok"}).then((token) {
    print(token);
    test.decode("bad.jwt.here")
      ..then((n_tok) => print(n_tok))
      ..catchError((e) => print(e));
  });

And this is the output

dart server.dart
eyJ0eXAiOiJKV1QiLCJhbGciOiJTSEEyNTYifQ==.eyJsdSI6Im9rIn0=.E3TjGiPGSJOIVZFFECJ0OSr0jAWojIfF7MqFNTbFPmI=
Bad token
Unhandled exception:
Uncaught Error: Bad token
#0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:820)
#1      _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:126)

I don't understand why we tell me that my error is uncaught while it's printed...

2

2 Answers

3
votes

I think you misused .. instead of . for chaining future. See https://www.dartlang.org/docs/tutorials/futures/#handling-errors

instead of

test.decode("bad.jwt.here")
  ..then((n_tok) => print(n_tok))
  ..catchError((e) => print(e));

can you try

test.decode("bad.jwt.here")
  .then((n_tok) => print(n_tok))
  .catchError((e) => print(e));
2
votes

Have a look at this document about how Futures work - https://www.dartlang.org/articles/futures-and-error-handling/.

In particular there is an example which says:

myFunc()
  .then((value) {
    doSomethingWith(value);
    ...
    throw("some arbitrary error");
  })
  .catchError(handleError);

If myFunc()’s Future completes with an error, then()’s Future completes with that error. The error is also handled by catchError().

Regardless of whether the error originated within myFunc() or within then(), catchError() successfully handles it.

That is consistent with what you're seeing.