| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library schedule_error; | 5 library schedule_error; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:stack_trace/stack_trace.dart'; |
| 10 |
| 9 import 'schedule.dart'; | 11 import 'schedule.dart'; |
| 10 import 'task.dart'; | 12 import 'task.dart'; |
| 11 import 'utils.dart'; | 13 import 'utils.dart'; |
| 12 | 14 |
| 13 /// A wrapper for errors that occur during a scheduled test. | 15 /// A wrapper for errors that occur during a scheduled test. |
| 14 class ScheduleError extends AsyncError { | 16 class ScheduleError extends AsyncError { |
| 15 /// The schedule during which this error occurred. | 17 /// The schedule during which this error occurred. |
| 16 final Schedule schedule; | 18 final Schedule schedule; |
| 17 | 19 |
| 18 /// The task that was running when this error occurred. This may be `null` if | 20 /// The task that was running when this error occurred. This may be `null` if |
| (...skipping 10 matching lines...) Expand all Loading... |
| 29 | 31 |
| 30 /// The state of the schedule at the time the error was detected. | 32 /// The state of the schedule at the time the error was detected. |
| 31 final ScheduleState _stateWhenDetected; | 33 final ScheduleState _stateWhenDetected; |
| 32 | 34 |
| 33 int get hashCode => schedule.hashCode ^ task.hashCode ^ queue.hashCode ^ | 35 int get hashCode => schedule.hashCode ^ task.hashCode ^ queue.hashCode ^ |
| 34 _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode ^ | 36 _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode ^ |
| 35 cause.hashCode; | 37 cause.hashCode; |
| 36 | 38 |
| 37 /// Creates a new [ScheduleError] wrapping [error]. The metadata in | 39 /// Creates a new [ScheduleError] wrapping [error]. The metadata in |
| 38 /// [AsyncError]s and [ScheduleError]s will be preserved. | 40 /// [AsyncError]s and [ScheduleError]s will be preserved. |
| 39 factory ScheduleError.from(Schedule schedule, error, {stackTrace, | 41 factory ScheduleError.from(Schedule schedule, error, {StackTrace stackTrace, |
| 40 AsyncError cause}) { | 42 AsyncError cause}) { |
| 41 if (error is ScheduleError) return error; | 43 if (error is ScheduleError) return error; |
| 42 | 44 |
| 43 if (error is AsyncError) { | 45 if (error is AsyncError) { |
| 44 // Overwrite the explicit stack trace, because it probably came from a | 46 // Overwrite the explicit stack trace, because it probably came from a |
| 45 // rethrow in the first place. | 47 // rethrow in the first place. |
| 46 stackTrace = error.stackTrace; | 48 stackTrace = error.stackTrace; |
| 47 if (cause == null) cause = error.cause; | 49 if (cause == null) cause = error.cause; |
| 48 error = error.error; | 50 error = error.error; |
| 49 } | 51 } |
| 50 | 52 |
| 51 if (stackTrace == null) { | 53 if (stackTrace == null) { |
| 52 try { | 54 try { |
| 53 throw ''; | 55 throw ''; |
| 54 } catch (_, thrownStackTrace) { | 56 } catch (_, thrownStackTrace) { |
| 55 stackTrace = thrownStackTrace; | 57 stackTrace = thrownStackTrace; |
| 56 } | 58 } |
| 57 } | 59 } |
| 58 | 60 |
| 59 return new ScheduleError(schedule, error, stackTrace, cause); | 61 return new ScheduleError(schedule, error, stackTrace, cause); |
| 60 } | 62 } |
| 61 | 63 |
| 62 ScheduleError(Schedule schedule, error, stackTrace, AsyncError cause) | 64 ScheduleError(Schedule schedule, error, StackTrace stackTrace, |
| 65 AsyncError cause) |
| 63 : super.withCause(error, stackTrace, cause), | 66 : super.withCause(error, stackTrace, cause), |
| 64 schedule = schedule, | 67 schedule = schedule, |
| 65 task = schedule.currentTask, | 68 task = schedule.currentTask, |
| 66 queue = schedule.currentQueue, | 69 queue = schedule.currentQueue, |
| 67 pendingCallbacks = schedule.currentQueue == null ? <String>[] | 70 pendingCallbacks = schedule.currentQueue == null ? <String>[] |
| 68 : schedule.currentQueue.pendingCallbacks.toList(), | 71 : schedule.currentQueue.pendingCallbacks.toList(), |
| 69 _stateWhenDetected = schedule.state; | 72 _stateWhenDetected = schedule.state; |
| 70 | 73 |
| 71 bool operator ==(other) => other is ScheduleError && task == other.task && | 74 bool operator ==(other) => other is ScheduleError && task == other.task && |
| 72 queue == other.queue && _stateWhenDetected == other._stateWhenDetected && | 75 queue == other.queue && _stateWhenDetected == other._stateWhenDetected && |
| 73 error == other.error && stackTrace == other.stackTrace && | 76 error == other.error && stackTrace == other.stackTrace && |
| 74 cause == other.cause; | 77 cause == other.cause; |
| 75 | 78 |
| 76 String toString() { | 79 String toString() { |
| 77 var result = new StringBuffer(); | 80 var result = new StringBuffer(); |
| 78 | 81 |
| 79 var errorString = error.toString(); | 82 var errorString = error.toString(); |
| 80 if (errorString.contains("\n")) { | 83 if (errorString.contains("\n")) { |
| 81 result.write('ScheduleError:\n'); | 84 result.write('ScheduleError:\n'); |
| 82 result.write(prefixLines(errorString.trim())); | 85 result.write(prefixLines(errorString.trim())); |
| 83 result.write("\n\n"); | 86 result.write("\n\n"); |
| 84 } else { | 87 } else { |
| 85 result.write('ScheduleError: "$errorString"\n'); | 88 result.write('ScheduleError: "$errorString"\n'); |
| 86 } | 89 } |
| 87 | 90 |
| 88 result.write('Stack trace:\n'); | 91 result.write('Stack trace:\n'); |
| 89 result.write(prefixLines(stackTrace.toString().trim())); | 92 result.write(prefixLines(terseTraceString(stackTrace))); |
| 90 result.write("\n\n"); | 93 result.write("\n\n"); |
| 91 | 94 |
| 92 if (task != null) { | 95 if (task != null) { |
| 93 result.write('Error detected during task in queue "$queue":\n'); | 96 result.write('Error detected during task in queue "$queue":\n'); |
| 94 result.write(task.generateTree()); | 97 result.write(task.generateTree()); |
| 95 } else if (_stateWhenDetected == ScheduleState.DONE) { | 98 } else if (_stateWhenDetected == ScheduleState.DONE) { |
| 96 result.write('Error detected after all tasks in the schedule had ' | 99 result.write('Error detected after all tasks in the schedule had ' |
| 97 'finished.'); | 100 'finished.'); |
| 98 } else if (_stateWhenDetected == ScheduleState.RUNNING) { | 101 } else if (_stateWhenDetected == ScheduleState.RUNNING) { |
| 99 result.write('Error detected when waiting for out-of-band callbacks in ' | 102 result.write('Error detected when waiting for out-of-band callbacks in ' |
| 100 'queue "$queue".'); | 103 'queue "$queue".'); |
| 101 } else { // _stateWhenDetected == ScheduleState.SET_UP | 104 } else { // _stateWhenDetected == ScheduleState.SET_UP |
| 102 result.write('Error detected before the schedule started running.'); | 105 result.write('Error detected before the schedule started running.'); |
| 103 } | 106 } |
| 104 | 107 |
| 105 if (!pendingCallbacks.isEmpty) { | 108 if (!pendingCallbacks.isEmpty) { |
| 106 result.write("\n\n"); | 109 result.write("\n\n"); |
| 107 result.writeln("Pending out-of-band callbacks:"); | 110 result.writeln("Pending out-of-band callbacks:"); |
| 108 for (var callback in pendingCallbacks) { | 111 for (var callback in pendingCallbacks) { |
| 109 result.writeln("* $callback"); | 112 result.writeln(prefixLines(callback, firstPrefix: "* ")); |
| 110 } | 113 } |
| 111 } | 114 } |
| 112 | 115 |
| 113 return result.toString().trim(); | 116 return result.toString().trim(); |
| 114 } | 117 } |
| 115 } | 118 } |
| OLD | NEW |