blob: 004b59122768555cc2b8c0a459dd17173740f66c [file] [log] [blame]
// Copyright (c) 2016, 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.
library fasta.errors;
import 'dart:async' show Future;
import 'command_line_reporting.dart' show shouldThrowOn;
import 'crash.dart' show safeToString;
import 'messages.dart'
show
LocatedMessage,
isVerbose,
noLength,
templateInternalProblemDebugAbort,
templateUnspecified;
import 'severity.dart' show Severity, severityTexts;
import 'crash.dart' show Crash, reportCrash, resetCrashReporting;
/// Used to report an error in input.
///
/// Avoid using this for reporting compile-time errors, instead use
/// `LibraryBuilder.addCompileTimeError` for those.
///
/// An input error is any error that isn't an internal error. We use the term
/// "input error" in favor of "user error". This way, if an input error isn't
/// handled correctly, the user will never see a stack trace that says "user
/// error".
dynamic deprecated_inputError(Uri uri, int charOffset, Object error) {
if (shouldThrowOn(Severity.error) && isVerbose) {
print(StackTrace.current);
}
throw new deprecated_InputError(uri, charOffset, error);
}
class deprecated_InputError {
final Uri uri;
final int charOffset;
final Object error;
deprecated_InputError(this.uri, int charOffset, this.error)
: this.charOffset = charOffset ?? -1;
toString() => "deprecated_InputError: $error";
/// Converts [error] to a [LocatedMessage] using [templateUnspecified]. Using
/// [templateUnspecified] is deprecated behavior.
///
/// Static method to discourage use and requiring call-sites to include the
/// text `deprecated_`.
static LocatedMessage deprecated_toMessage(deprecated_InputError error) {
if (error is DebugAbort) {
return error.toMessage();
} else {
return templateUnspecified
.withArguments(safeToString(error.error))
.withLocation(error.uri, error.charOffset, noLength);
}
}
}
class DebugAbort extends deprecated_InputError {
final StackTrace trace;
final Severity severity;
DebugAbort(Uri uri, int charOffset, this.severity, this.trace)
: super(uri, charOffset, "");
LocatedMessage toMessage() {
return templateInternalProblemDebugAbort
.withArguments(severityTexts[severity], "$trace")
.withLocation(uri, charOffset, noLength);
}
}
// TODO(ahe): Move this method to crash.dart when it's no longer using
// [deprecated_InputError].
Future<T> withCrashReporting<T>(
Future<T> Function() action, Uri Function() currentUri,
{T Function(LocatedMessage) onInputError}) async {
resetCrashReporting();
try {
return await action();
} on Crash {
rethrow;
} on DebugAbort {
rethrow;
} on deprecated_InputError catch (e, s) {
if (onInputError != null) {
return onInputError(deprecated_InputError.deprecated_toMessage(e));
} else {
return reportCrash(e, s, currentUri());
}
} catch (e, s) {
return reportCrash(e, s, currentUri());
}
}