OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library unittest.remote_exception; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:isolate'; | |
9 | |
10 import 'package:stack_trace/stack_trace.dart'; | |
11 | |
12 import 'expect.dart'; | |
13 | |
14 /// An exception that was thrown remotely. | |
15 /// | |
16 /// This could be an exception thrown in a different isolate, a different | |
17 /// process, or on an entirely different computer. | |
18 class RemoteException implements Exception { | |
19 /// The original exception's message, if it had one. | |
20 /// | |
21 /// If the original exception was a plain string, this will contain that | |
22 /// string. | |
23 final String message; | |
24 | |
25 /// The value of the original exception's `runtimeType.toString()`. | |
26 final String type; | |
27 | |
28 /// The value of the original exception's `toString()`. | |
29 final String _toString; | |
30 | |
31 /// Serializes [error] and [stackTrace] into a JSON-safe object. | |
32 /// | |
33 /// Other than JSON- and isolate-safety, no guarantees are made about the | |
34 /// serialized format. | |
35 static serialize(error, StackTrace stackTrace) { | |
36 var message; | |
37 if (error is String) { | |
38 message = error; | |
39 } else { | |
40 try { | |
41 message = error.message.toString(); | |
42 } on NoSuchMethodError catch (_) { | |
43 // Do nothing. | |
44 } | |
45 } | |
46 | |
47 // It's possible (although unlikely) for a user-defined class to have | |
48 // multiple of these supertypes. That's fine, though, since we only care | |
49 // about core-library-raised IsolateSpawnExceptions anyway. | |
50 var supertype; | |
51 if (error is TestFailure) { | |
52 supertype = 'TestFailure'; | |
53 } else if (error is IsolateSpawnException) { | |
54 supertype = 'IsolateSpawnException'; | |
55 } | |
56 | |
57 return { | |
58 'message': message, | |
59 'type': error.runtimeType.toString(), | |
60 'supertype': supertype, | |
61 'toString': error.toString(), | |
62 'stackChain': new Chain.forTrace(stackTrace).toString() | |
63 }; | |
64 } | |
65 | |
66 /// Deserializes an exception serialized with [RemoteException.serialize]. | |
67 /// | |
68 /// The returned [AsyncError] is guaranteed to have a [RemoteException] as its | |
69 /// error and a [Chain] as its stack trace. | |
70 static AsyncError deserialize(serialized) { | |
71 return new AsyncError( | |
72 _deserializeException(serialized), | |
73 new Chain.parse(serialized['stackChain'])); | |
74 } | |
75 | |
76 /// Deserializes the exception portion of [serialized]. | |
77 static RemoteException _deserializeException(serialized) { | |
78 var message = serialized['message']; | |
79 var type = serialized['type']; | |
80 var toString = serialized['toString']; | |
81 | |
82 switch (serialized['supertype']) { | |
83 case 'TestFailure': | |
84 return new _RemoteTestFailure(message, type, toString); | |
85 case 'IsolateSpawnException': | |
86 return new _RemoteIsolateSpawnException(message, type, toString); | |
87 default: | |
88 return new RemoteException._(message, type, toString); | |
89 } | |
90 } | |
91 | |
92 RemoteException._(this.message, this.type, this._toString); | |
93 | |
94 String toString() => _toString; | |
95 } | |
96 | |
97 /// A subclass of [RemoteException] that implements [TestFailure]. | |
98 /// | |
99 /// It's important to preserve [TestFailure]-ness, because tests have different | |
100 /// results depending on whether an exception was a failure or an error. | |
101 class _RemoteTestFailure extends RemoteException implements TestFailure { | |
102 _RemoteTestFailure(String message, String type, String toString) | |
103 : super._(message, type, toString); | |
104 } | |
105 | |
106 /// A subclass of [RemoteException] that implements [IsolateSpawnException]. | |
107 class _RemoteIsolateSpawnException extends RemoteException | |
108 implements IsolateSpawnException { | |
109 _RemoteIsolateSpawnException(String message, String type, String toString) | |
110 : super._(message, type, toString); | |
111 } | |
OLD | NEW |