4
votes

I have this test:

     Future f = neo4d.nodes.delete(1);
      f.then(((_) {  
      })).catchError((e){
        expect(e.statusCode, equals(409));
      });
      return f;
    });

that currently blows up, since the e.statusCode is 404 instead of 409. I want the test to just fail but instead the whole test suite is stopped because of an uncaught exception. How do I catch the exception (and fail the test) and stop it from blowing up all other tests?

This is the output I get when I run the code above:

[2014-03-06 14:44:32.020] DEBUG http: R10: Received data in 9ms with status 404: [{
  "message" : "Cannot find node with id [1] in database.",
  "exception" : "NodeNotFoundException",
  "fullname" : "org.neo4j.server.rest.web.NodeNotFoundException",
  "stacktrace" : [ "org.neo4j.server.rest.web.DatabaseActions.node(DatabaseActions.java:183)", "org.neo4j.server.rest.web.DatabaseActions.deleteNode(DatabaseActions.java:233)", "org.neo4j.server.rest.web.RestfulGraphDatabase.deleteNode(RestfulGraphDatabase.java:279)", "java.lang.reflect.Method.invoke(Method.java:601)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)", "java.lang.Thread.run(Thread.java:722)" ]
}]
Uncaught Error: Expected: 409
  Actual: 404

Stack Trace: 
#0      SimpleConfiguration.onExpectFailure (package:unittest/src/simple_configuration.dart:141:7)
#1      _ExpectFailureHandler.fail (package:unittest/src/simple_configuration.dart:15:28)
#2      DefaultFailureHandler.failMatch (package:unittest/src/expect.dart:117:9)
#3      expect (package:unittest/src/expect.dart:75:29)
#4      nodes... (file:///Users/oskbor/Projects/neo4dart/test/alltests.dart:202:15)
#5      _invokeErrorHandler (dart:async/async_error.dart:12)
#6      _Future._propagateToListeners. (dart:async/future_impl.dart:469)
#7      _rootRun (dart:async/zone.dart:683)
#8      _RootZone.run (dart:async/zone.dart:823)
#9      _Future._propagateToListeners (dart:async/future_impl.dart:445)
#10     _Future._propagateMultipleListeners (dart:async/future_impl.dart:384)
#11     _Future._propagateToListeners (dart:async/future_impl.dart:411)
#12     _Future._completeError (dart:async/future_impl.dart:315)
#13     _Future._asyncCompleteError. (dart:async/future_impl.dart:367)
#14     _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#15     _createTimer. (dart:async-patch/timer_patch.dart:11)
#16     _Timer._createTimerHandler._handleTimeout (timer_impl.dart:151)
#17     _Timer._createTimerHandler. (timer_impl.dart:166)
#18     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:93)


Unhandled exception:
Expected: 409
  Actual: 404

#0      _rootHandleUncaughtError.. (dart:async/zone.dart:677)
#1      _asyncRunCallback (dart:async/schedule_microtask.dart:18)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:21)
#3      _createTimer. (dart:async-patch/timer_patch.dart:11)
#4      _Timer._createTimerHandler._handleTimeout (timer_impl.dart:151)
#5      _Timer._createTimerHandler._handleTimeout (timer_impl.dart:159)
#6      _Timer._createTimerHandler._handleTimeout (timer_impl.dart:159)
#7      _Timer._createTimerHandler. (timer_impl.dart:166)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:93)

regards Oskar

1

1 Answers

3
votes

An asynchronous function, i.e. a function returning a Future, can "throw" two different ways:

It can throw synchronously and not even return a Future in the first place:

Future<int> doSomethingAsync() {
  throw new Exception("No! I don't want to even get started!");
}

Or, it can throw asynchronously - i.e. return a Future which then asynchronously throws an error instead of completing:

Future<int> doSomethingAsync() {
  return new Future.error(new Exception("Here's your future, but it'll fail."));
}

Your async call

neo4d.nodes.delete(1)

must be of the former type: it throws right away without even returning a Future. That's why the exception doesn't get caught by .catchError and blows up your entire test suite instead.

You want to either update neo4d.nodes.delete and make it throw asynchronously. Or, if that can't be done, wrap your test in a good old synchronous try-catch:

  try {
    neo4d.nodes.delete(1).then(((_) { expect(0, 1);  }));
  }
  catch (e) {
    expect(e.statusCode, equals(409));
  }