Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Unified Diff: sdk/lib/core/exceptions.dart

Issue 389603002: Add extra information to FormatException. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/core/date_time.dart ('k') | sdk/lib/core/uri.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/core/exceptions.dart
diff --git a/sdk/lib/core/exceptions.dart b/sdk/lib/core/exceptions.dart
index 800a6529ab209a109d82c40a115d020f15734e16..bccc8b2f0b8724adfa2b348cd8a65dd2ba8332e6 100644
--- a/sdk/lib/core/exceptions.dart
+++ b/sdk/lib/core/exceptions.dart
@@ -44,13 +44,122 @@ class FormatException implements Exception {
* A message describing the format error.
*/
final String message;
+ /**
+ * The source that caused the error.
nweiz 2014/07/14 19:33:50 The documentation and name doesn't make it clear a
Lasse Reichstein Nielsen 2014/07/15 08:55:59 I'll try to make it more explicit, including the w
+ *
+ * This is usually a [String], but can be other types too. If it is a string,
+ * parts of it may be included in the [toString] message.
+ *
+ * May also be `null` if omitted.
+ */
+ final source;
nweiz 2014/07/14 19:33:49 It would be a lot more useful to consumers of this
Lasse Reichstein Nielsen 2014/07/15 08:55:59 I don't want to mandate a type. It will almost alw
+ /**
+ * The position in source where the error was detected.
nweiz 2014/07/14 19:33:49 Please be clearer about what you mean by "position
Lasse Reichstein Nielsen 2014/07/15 08:55:59 I like "offset", so I changed it everywhere. Also
+ *
+ * May be omitted. If present, [source] should also be present.
+ */
+ final int position;
/**
* Creates a new FormatException with an optional error [message].
+ *
+ * Optionally also supply the [source] that had the incorrect format, and
+ * even the [position] in the format where this was detected.
*/
- const FormatException([this.message = ""]);
+ const FormatException([this.message = "", this.source, this.position]);
- String toString() => "FormatException: $message";
+ /**
+ * Returns a description of the format exception.
+ *
+ * The description always contains the [message].
+ * If [source] was provided, the description will contain (at least a part of)
+ * the source.
+ * If [position] is also provided, the part of the source included will
+ * contain that position, and the position will be marked.
+ *
+ * If the source contains a line break before position, only the line
+ * containing position will be included, and its line number will also be
+ * part of the description. Line and character offsets are 1-based.
+ */
+ String toString() {
+ String report = "FormatException";
+ if (message != null && message.isNotEmpty) {
+ report = "$report: $message";
+ }
+ int position = this.position;
+ if (source is! String) {
+ if (position != null) {
+ report += " (at position $position)";
+ }
+ return report;
+ }
+ if (position != null && (position < 0 || position > source.length)) {
+ position = null;
+ }
+ // Source is string and position is null or valid.
+ if (position == null) {
+ String source = this.source;
+ if (source.length > 78) {
+ source = source.substring(0, 75) + "...";
+ }
+ return "$report\n$source";
+ }
+ int lineNum = 1;
+ int lineStart = 0;
+ bool lastWasCR;
+ for (int i = 0; i < position; i++) {
+ int char = source.codeUnitAt(i);
+ if (char == 0x0a) {
+ if (lineStart != i || !lastWasCR) {
+ lineNum++;
+ }
+ lineStart = i + 1;
+ lastWasCR = false;
+ } else if (char == 0x0d) {
+ lineNum++;
+ lineStart = i + 1;
+ lastWasCR = true;
+ }
+ }
+ if (lineNum > 1) {
+ report += " (at line $lineNum, character ${position - lineStart + 1})\n";
+ } else {
+ report += " (at character ${position + 1})\n";
+ }
+ int lineEnd = source.length;
+ for (int i = position; i < source.length; i++) {
+ int char = source.codeUnitAt(i);
+ if (char == 0x0a || char == 0x0d) {
+ lineEnd = i;
+ break;
+ }
+ }
+ int length = lineEnd - lineStart;
+ int start = lineStart;
+ int end = lineEnd;
+ String prefix = "";
+ String postfix = "";
+ if (length > 78) {
+ // Can't show entire line. Try to anchor at the nearest end, if
+ // one is within reach.
+ int index = position - lineStart;
+ if (index < 75) {
+ end = start + 75;
+ postfix = "...";
+ } else if (end - position < 75) {
+ start = end - 75;
+ prefix = "...";
+ } else {
+ // Neither end is near, just pick an area around the position.
+ start = position - 36;
+ end = position + 36;
+ prefix = postfix = "...";
+ }
+ }
+ String slice = source.substring(start, end);
+ int markOffset = position - start + prefix.length;
+ return "$report$prefix$slice$postfix\n${" " * markOffset}^\n";
+ }
}
class IntegerDivisionByZeroException implements Exception {
« no previous file with comments | « sdk/lib/core/date_time.dart ('k') | sdk/lib/core/uri.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698