| 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 'schedule.dart'; | 9 import 'schedule.dart'; |
| 10 import 'task.dart'; | 10 import 'task.dart'; |
| 11 import 'utils.dart'; | 11 import 'utils.dart'; |
| 12 | 12 |
| 13 /// A wrapper for errors that occur during a scheduled test. | 13 /// A wrapper for errors that occur during a scheduled test. |
| 14 class ScheduleError extends AsyncError { | 14 class ScheduleError extends AsyncError { |
| 15 /// The schedule during which this error occurred. | 15 /// The schedule during which this error occurred. |
| 16 final Schedule schedule; | 16 final Schedule schedule; |
| 17 | 17 |
| 18 /// The task that was running when this error occurred. This may be `null` if | 18 /// The task that was running when this error occurred. This may be `null` if |
| 19 /// there was no such task. | 19 /// there was no such task. |
| 20 final Task task; | 20 final Task task; |
| 21 | 21 |
| 22 /// Whether the schedule was finished executing at the time the error was | 22 /// The task queue that was running when this error occured. This may be |
| 23 /// detected. | 23 /// `null` if there was no such queue. |
| 24 final bool _scheduleWasDone; | 24 final TaskQueue queue; |
| 25 |
| 26 /// The state of the schedule at the time the error was detected. |
| 27 final ScheduleState _stateWhenDetected; |
| 25 | 28 |
| 26 /// Creates a new [ScheduleError] wrapping [error]. The metadata in | 29 /// Creates a new [ScheduleError] wrapping [error]. The metadata in |
| 27 /// [AsyncError]s and [ScheduleError]s will be preserved. | 30 /// [AsyncError]s and [ScheduleError]s will be preserved. |
| 28 factory ScheduleError.from(Schedule schedule, error, {stackTrace, | 31 factory ScheduleError.from(Schedule schedule, error, {stackTrace, |
| 29 AsyncError cause, Task task}) { | 32 AsyncError cause}) { |
| 30 if (error is ScheduleError) { | 33 if (error is ScheduleError) { |
| 31 if (schedule == null) schedule = error.schedule; | 34 if (schedule == null) schedule = error.schedule; |
| 32 if (task == null) task = error.task; | |
| 33 } | 35 } |
| 34 | 36 |
| 35 if (error is AsyncError) { | 37 if (error is AsyncError) { |
| 36 // Overwrite the explicit stack trace, because it probably came from a | 38 // Overwrite the explicit stack trace, because it probably came from a |
| 37 // rethrow in the first place. | 39 // rethrow in the first place. |
| 38 stackTrace = error.stackTrace; | 40 stackTrace = error.stackTrace; |
| 39 if (cause == null) cause = error.cause; | 41 if (cause == null) cause = error.cause; |
| 40 error = error.error; | 42 error = error.error; |
| 41 } | 43 } |
| 42 | 44 |
| 43 return new ScheduleError(schedule, error, stackTrace, cause, task); | 45 return new ScheduleError(schedule, error, stackTrace, cause); |
| 44 } | 46 } |
| 45 | 47 |
| 46 ScheduleError(Schedule schedule, error, stackTrace, AsyncError cause, | 48 ScheduleError(Schedule schedule, error, stackTrace, AsyncError cause) |
| 47 this.task) | |
| 48 : super.withCause(error, stackTrace, cause), | 49 : super.withCause(error, stackTrace, cause), |
| 49 this.schedule = schedule, | 50 this.schedule = schedule, |
| 50 this._scheduleWasDone = schedule.done; | 51 this.task = schedule.currentTask, |
| 52 this.queue = schedule.currentQueue, |
| 53 this._stateWhenDetected = schedule.state; |
| 51 | 54 |
| 52 String toString() { | 55 String toString() { |
| 53 var result = new StringBuffer(); | 56 var result = new StringBuffer(); |
| 54 | 57 |
| 55 var errorString = error.toString(); | 58 var errorString = error.toString(); |
| 56 if (errorString.contains("\n")) { | 59 if (errorString.contains("\n")) { |
| 57 result.add('ScheduleError:\n'); | 60 result.add('ScheduleError:\n'); |
| 58 result.add(prefixLines(errorString.trim())); | 61 result.add(prefixLines(errorString.trim())); |
| 59 result.add("\n\n"); | 62 result.add("\n\n"); |
| 60 } else { | 63 } else { |
| 61 result.add('ScheduleError: "$errorString"\n'); | 64 result.add('ScheduleError: "$errorString"\n'); |
| 62 } | 65 } |
| 63 | 66 |
| 64 result.add('Stack trace:\n'); | 67 result.add('Stack trace:\n'); |
| 65 result.add(prefixLines(stackTrace.toString().trim())); | 68 result.add(prefixLines(stackTrace.toString().trim())); |
| 66 result.add("\n\n"); | 69 result.add("\n\n"); |
| 67 | 70 |
| 68 if (task != null) { | 71 if (task != null) { |
| 69 result.add('Error detected during task in queue "${task.queue}":\n'); | 72 result.add('Error detected during task in queue "$queue":\n'); |
| 70 result.add(task.generateTree()); | 73 result.add(task.generateTree()); |
| 71 } else if (_scheduleWasDone) { | 74 } else if (_stateWhenDetected == ScheduleState.DONE) { |
| 72 result.add('Error detected after all tasks in the queue had finished.'); | 75 result.add('Error detected after all tasks in the schedule had ' |
| 73 } else { | 76 'finished.'); |
| 77 } else if (_stateWhenDetected == ScheduleState.RUNNING) { |
| 78 result.add('Error detected when waiting for out-of-band callbacks in ' |
| 79 'queue "$queue".'); |
| 80 } else { // _stateWhenDetected == ScheduleState.SET_UP |
| 74 result.add('Error detected before the schedule started running.'); | 81 result.add('Error detected before the schedule started running.'); |
| 75 } | 82 } |
| 76 | 83 |
| 77 return result.toString(); | 84 return result.toString(); |
| 78 } | 85 } |
| 79 } | 86 } |
| OLD | NEW |