Index: lib/src/remote_exception.dart |
diff --git a/lib/src/remote_exception.dart b/lib/src/remote_exception.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7d51db51574f5f893b3f025fb03b39409fd6ae1d |
--- /dev/null |
+++ b/lib/src/remote_exception.dart |
@@ -0,0 +1,88 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library unittest.remote_exception; |
+ |
+import 'dart:async'; |
+ |
+import 'package:stack_trace/stack_trace.dart'; |
+ |
+import 'expect.dart'; |
+ |
+/// An exception that was thrown remotely. |
+/// |
+/// This could be an exception thrown in a different isolate, a different |
+/// process, or on an entirely different computer. |
+class RemoteException implements Exception { |
+ /// The original exception's message, if it had one. |
+ /// |
+ /// If the original exception was a plain string, this will contain that |
+ /// string. |
+ final String message; |
+ |
+ /// The value of the original exception's `runtimeType.toString()`. |
+ final String type; |
+ |
+ /// The value of the original exception's `toString()`. |
+ final String _toString; |
+ |
+ /// Serializes [error] and [stackTrace] into a JSON-safe object. |
+ /// |
+ /// Other than JSON- and isolate-safety, no guarantees are made about the |
kevmoo
2015/02/12 02:24:29
Comments about what's expected for [error]?
Strin
nweiz
2015/02/12 19:03:41
Any error object—which is to say, theoretically an
|
+ /// serialized format. |
+ static serialize(error, StackTrace stackTrace) { |
+ var message; |
+ if (error is String) { |
+ message = error; |
+ } else { |
+ try { |
+ message = error.message.toString(); |
+ } on NoSuchMethodError catch (_) { |
+ // Do nothing. |
kevmoo
2015/02/12 02:24:29
Fall back to message.toString()?
nweiz
2015/02/12 19:03:41
If we're here, there is no message property.
|
+ } |
+ } |
+ |
+ return { |
+ 'message': message, |
+ 'type': error.runtimeType.toString(), |
+ 'toString': error.toString(), |
+ 'stackChain': new Chain.forTrace(stackTrace).toString() |
+ }; |
+ } |
+ |
+ /// Deserializes an exception serialized with [RemoteException.serialize]. |
+ /// |
+ /// The returned [AsyncError] is guaranteed to have a [RemoteException] as its |
+ /// error and a [Chain] as its stack trace. |
+ static AsyncError deserialize(serialized) { |
+ var exception; |
+ if (serialized['type'] == 'TestFailure') { |
kevmoo
2015/02/12 02:24:29
You could be a bit more clever coordinating betwee
nweiz
2015/02/12 19:03:41
Good point. Done.
|
+ exception = new RemoteTestFailure._(serialized['message']); |
+ } else { |
+ exception = new RemoteException._( |
+ serialized['message'], |
+ serialized['type'], |
+ serialized['toString']); |
+ } |
+ |
+ return new AsyncError(exception, new Chain.parse(serialized['stackChain'])); |
+ } |
+ |
+ RemoteException._(this.message, this.type, this._toString); |
+ |
+ String toString() => _toString; |
+} |
+ |
+/// A subclass of [RemoteException] that implements [TestFailure]. |
+/// |
+/// It's important to preserve [TestFailure]-ness, because tests have different |
+/// results depending on whether an exception was a failure or an error. |
+class RemoteTestFailure implements TestFailure, RemoteException { |
kevmoo
2015/02/12 02:24:29
Analyzer complains that this class does not implem
nweiz
2015/02/12 19:03:41
Done.
|
+ final String message; |
+ final type = "TestFailure"; |
kevmoo
2015/02/12 02:24:29
Could this be a property? Avoid allocating a Strin
nweiz
2015/02/12 19:03:41
I removed this, but:
On 2015/02/12 02:24:29, kevm
|
+ |
+ RemoteTestFailure._(this.message); |
+ |
+ String toString() => message; |
+} |