blob: fcde747d835774675b373dbd5e8b5ca68325f861 [file] [log] [blame]
// Copyright (c) 2014, 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.
import 'dart:io';
import 'dart:isolate';
import 'package:args/command_runner.dart';
import 'package:http/http.dart' as http;
import 'package:stack_trace/stack_trace.dart';
import 'package:yaml/yaml.dart';
import 'dart.dart';
/// An exception class for exceptions that are intended to be seen by the user.
///
/// These exceptions won't have any debugging information printed when they're
/// thrown.
class ApplicationException implements Exception {
final String message;
ApplicationException(this.message);
@override
String toString() => message;
}
/// A subclass of [ApplicationException] that occurs when running a subprocess
/// has failed.
class RunProcessException extends ApplicationException {
RunProcessException(String message) : super(message);
}
/// An exception class for exceptions that are intended to be seen by the user
/// and are associated with a problem in a file at some path.
class FileException implements ApplicationException {
@override
final String message;
/// The path to the file that was missing or erroneous.
final String path;
FileException(this.message, this.path);
@override
String toString() => message;
}
/// A class for exceptions that wrap other exceptions.
class WrappedException extends ApplicationException {
/// The underlying exception that [this] is wrapping, if any.
final Object? innerError;
/// The stack chain for [innerError] if it exists.
final Chain? innerChain;
WrappedException(String message, this.innerError, [StackTrace? innerTrace])
: innerChain = innerTrace == null ? null : Chain.forTrace(innerTrace),
super(message);
}
/// A class for exceptions that shouldn't be printed at the top level.
///
/// This is usually used when an exception has already been printed using
/// [log.exception].
class SilentException extends WrappedException {
SilentException(Object? innerError, [StackTrace? innerTrace])
: super(innerError.toString(), innerError, innerTrace);
}
/// A class for errors in a command's input data.
///
/// This corresponds to the `data` exit code.
class DataException extends ApplicationException {
DataException(String message) : super(message);
}
/// An exception indicating that the users configuration is invalid.
///
/// This corresponds to the `config` exit code;
class ConfigException extends ApplicationException {
ConfigException(String message) : super(message);
}
/// An class for exceptions where a package could not be found in a [Source].
///
/// The source is responsible for wrapping its internal exceptions in this so
/// that other code in pub can use this to show a more detailed explanation of
/// why the package was being requested.
class PackageNotFoundException extends WrappedException {
/// A hint indicating an action the user could take to resolve this problem.
///
/// This will be printed after the package resolution conflict.
final String? hint;
PackageNotFoundException(
String message, {
Object? innerError,
StackTrace? innerTrace,
this.hint,
}) : super(message, innerError, innerTrace);
@override
String toString() => 'Package not available ($message).';
}
/// Returns whether [error] is a user-facing error object.
///
/// This includes both [ApplicationException] and any dart:io errors.
bool isUserFacingException(error) {
// TODO(nweiz): unify this list with _userFacingExceptions when issue 5897 is
// fixed.
return error is ApplicationException ||
error is AnalyzerErrorGroup ||
error is IsolateSpawnException ||
error is IOException ||
error is http.ClientException ||
error is YamlException ||
error is UsageException;
}