| // Copyright (c) 2012, 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. |
| |
| part of dart.core; |
| |
| class Error { |
| /** |
| * Safely convert a value to a [String] description. |
| * |
| * The conversion is guaranteed to not throw, so it won't use the object's |
| * toString method. |
| */ |
| static String safeToString(Object object) { |
| if (object is int || object is double || object is bool || null == object) { |
| return object.toString(); |
| } |
| if (object is String) { |
| String string = object; |
| StringBuffer buffer = new StringBuffer('"'); |
| const int TAB = 0x09; |
| const int NEWLINE = 0x0a; |
| const int CARRIGE_RETURN = 0x0d; |
| const int BACKSLASH = 0x5c; |
| const int DOUBLE_QUOTE = 0x22; |
| const int DIGIT_ZERO = 0x30; |
| const int LOWERCASE_A = 0x61; |
| const int MAX_CONTROL = 0x1f; |
| for (int i = 0; i < string.length; i++) { |
| int codeUnit = string.codeUnitAt(i); |
| if (codeUnit <= MAX_CONTROL) { |
| if (codeUnit == NEWLINE) { |
| buffer.write(r"\n"); |
| } else if (codeUnit == CARRIGE_RETURN) { |
| buffer.write(r"\r"); |
| } else if (codeUnit == TAB) { |
| buffer.write(r"\t"); |
| } else { |
| buffer.write(r"\x"); |
| // Convert code in range 0x00 .. 0x1f to hex a two-digit hex string. |
| if (codeUnit < 0x10) { |
| buffer.write("0"); |
| } else { |
| buffer.write("1"); |
| codeUnit -= 0x10; |
| } |
| // Single digit to hex. |
| buffer.writeCharCode(codeUnit < 10 ? DIGIT_ZERO + codeUnit |
| : LOWERCASE_A - 10 + codeUnit); |
| } |
| } else if (codeUnit == BACKSLASH) { |
| buffer.write(r"\\"); |
| } else if (codeUnit == DOUBLE_QUOTE) { |
| buffer.write(r'\"'); |
| } else { |
| buffer.writeCharCode(codeUnit); |
| } |
| } |
| buffer.write('"'); |
| return buffer.toString(); |
| } |
| return _objectToString(object); |
| } |
| |
| external static String _objectToString(Object object); |
| |
| external StackTrace get stackTrace; |
| } |
| |
| /** |
| * Error thrown by the runtime system when an assert statement fails. |
| */ |
| class AssertionError extends Error { |
| } |
| |
| /** |
| * Error thrown by the runtime system when a type assertion fails. |
| */ |
| class TypeError extends AssertionError { |
| } |
| |
| /** |
| * Error thrown by the runtime system when a cast operation fails. |
| */ |
| class CastError extends Error { |
| } |
| |
| /** |
| * Error thrown when attempting to throw [:null:]. |
| */ |
| class NullThrownError extends Error { |
| NullThrownError(); |
| String toString() => "Throw of null."; |
| } |
| |
| /** |
| * Error thrown when a function is passed an unacceptable argument. |
| */ |
| class ArgumentError extends Error { |
| final message; |
| |
| /** The [message] describes the erroneous argument. */ |
| ArgumentError([this.message]); |
| |
| String toString() { |
| if (message != null) { |
| return "Illegal argument(s): $message"; |
| } |
| return "Illegal argument(s)"; |
| } |
| } |
| |
| /** |
| * Error thrown because of an index outside of the valid range. |
| * |
| */ |
| class RangeError extends ArgumentError { |
| // TODO(lrn): This constructor should be called only with string values. |
| // It currently isn't in all cases. |
| /** |
| * Create a new [RangeError] with the given [message]. |
| * |
| * Temporarily made const for backwards compatibilty. |
| */ |
| RangeError(var message) : super(message); |
| |
| /** Create a new [RangeError] with a message for the given [value]. */ |
| RangeError.value(num value) : super("value $value"); |
| |
| /** Create a new [RangeError] with a message for a value and a range. */ |
| RangeError.range(num value, num start, num end) |
| : super("value $value not in range $start..$end"); |
| |
| String toString() => "RangeError: $message"; |
| } |
| |
| |
| /** |
| * Error thrown when control reaches the end of a switch case. |
| * |
| * The Dart specification requires this error to be thrown when |
| * control reaches the end of a switch case (except the last case |
| * of a switch) without meeting a break or similar end of the control |
| * flow. |
| */ |
| class FallThroughError extends Error { |
| FallThroughError(); |
| } |
| |
| |
| class AbstractClassInstantiationError extends Error { |
| final String _className; |
| AbstractClassInstantiationError(String this._className); |
| String toString() => "Cannot instantiate abstract class: '$_className'"; |
| } |
| |
| |
| /** |
| * Error thrown by the default implementation of [:noSuchMethod:] on [Object]. |
| */ |
| class NoSuchMethodError extends Error { |
| final Object _receiver; |
| final Symbol _memberName; |
| final List _arguments; |
| final Map<Symbol, dynamic> _namedArguments; |
| final List _existingArgumentNames; |
| |
| /** |
| * Create a [NoSuchMethodError] corresponding to a failed method call. |
| * |
| * The [receiver] is the receiver of the method call. |
| * That is, the object on which the method was attempted called. |
| * If the receiver is `null`, it is interpreted as a call to a top-level |
| * function of a library. |
| * |
| * The [memberName] is a [Symbol] representing the name of the called method |
| * or accessor. It should not be `null`. |
| * |
| * The [positionalArguments] is a list of the positional arguments that the |
| * method was called with. If `null`, it is considered equivalent to the |
| * empty list. |
| * |
| * The [namedArguments] is a map from [Symbol]s to the values of named |
| * arguments that the method was called with. |
| * |
| * The optional [exisitingArgumentNames] is the expected parameters of a |
| * method with the same name on the receiver, if available. This is |
| * the signature of the method that would have been called if the parameters |
| * had matched. |
| */ |
| NoSuchMethodError(Object receiver, |
| Symbol memberName, |
| List positionalArguments, |
| Map<Symbol ,dynamic> namedArguments, |
| [List existingArgumentNames = null]) |
| : _receiver = receiver, |
| _memberName = memberName, |
| _arguments = positionalArguments, |
| _namedArguments = namedArguments, |
| _existingArgumentNames = existingArgumentNames; |
| |
| external String toString(); |
| } |
| |
| |
| /** |
| * The operation was not allowed by the object. |
| * |
| * This [Error] is thrown when an instance cannot implement one of the methods |
| * in its signature. |
| */ |
| class UnsupportedError extends Error { |
| final String message; |
| UnsupportedError(this.message); |
| String toString() => "Unsupported operation: $message"; |
| } |
| |
| |
| /** |
| * Thrown by operations that have not been implemented yet. |
| * |
| * This [Error] is thrown by unfinished code that hasn't yet implemented |
| * all the features it needs. |
| * |
| * If a class is not intending to implement the feature, it should throw |
| * an [UnsupportedError] instead. This error is only intended for |
| * use during development. |
| */ |
| class UnimplementedError extends Error implements UnsupportedError { |
| final String message; |
| UnimplementedError([String this.message]); |
| String toString() => (this.message != null |
| ? "UnimplementedError: $message" |
| : "UnimplementedError"); |
| } |
| |
| |
| /** |
| * The operation was not allowed by the current state of the object. |
| * |
| * This is a generic error used for a variety of different erroneous |
| * actions. The message should be descriptive. |
| */ |
| class StateError extends Error { |
| final String message; |
| StateError(this.message); |
| String toString() => "Bad state: $message"; |
| } |
| |
| |
| /** |
| * Error occurring when a collection is modified during iteration. |
| * |
| * Some modifications may be allowed for some collections, so each collection |
| * ([Iterable] or similar collection of values) should declare which operations |
| * are allowed during an iteration. |
| */ |
| class ConcurrentModificationError extends Error { |
| /** The object that was modified in an incompatible way. */ |
| final Object modifiedObject; |
| |
| ConcurrentModificationError([this.modifiedObject]); |
| |
| String toString() { |
| if (modifiedObject == null) { |
| return "Concurrent modification during iteration."; |
| } |
| return "Concurrent modification during iteration: " |
| "${Error.safeToString(modifiedObject)}."; |
| } |
| } |
| |
| |
| class OutOfMemoryError implements Error { |
| const OutOfMemoryError(); |
| String toString() => "Out of Memory"; |
| |
| StackTrace get stackTrace => null; |
| } |
| |
| |
| class StackOverflowError implements Error { |
| const StackOverflowError(); |
| String toString() => "Stack Overflow"; |
| |
| StackTrace get stackTrace => null; |
| } |
| |
| /** |
| * Error thrown when a lazily initialized variable cannot be initialized. |
| * |
| * A static/library variable with an initializer expression is initialized |
| * the first time it is read. If evaluating the initializer expression causes |
| * another read of the variable, this error is thrown. |
| */ |
| class CyclicInitializationError extends Error { |
| final String variableName; |
| CyclicInitializationError([this.variableName]); |
| String toString() => variableName == null |
| ? "Reading static variable during its initialization" |
| : "Reading static variable '$variableName' during its initialization"; |
| } |