blob: b5f838d750e75237ec290dccbaa4f2c2ee26fa32 [file] [log] [blame]
// Copyright (c) 2020, 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 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
/// Error thrown when a function is passed an invalid path.
class PathError extends ArgumentError {
/// The full path that caused the error
final Iterable<Object> path;
/// The subpath that caused the error
final Iterable<Object> subPath;
/// The last element of [path] that could be traversed.
YamlNode parent;
PathError(this.path, this.subPath, this.parent, [String message])
: super.value(subPath, 'path', message);
PathError.unexpected(this.path, String message)
: subPath = path,
String toString() {
if (message == null) {
var errorMessage = 'Failed to traverse to subpath $subPath!';
if (subPath.isNotEmpty) {
errorMessage +=
' Parent $parent does not contain key or index ${subPath.last}';
return 'Invalid path: $path. $errorMessage.';
return 'Invalid path: $path. $message';
/// Error thrown when the path contains an alias along the way.
/// When a path contains an aliased node, the behavior becomes less well-defined
/// because we cannot be certain if the user wishes for the change to
/// propagate throughout all the other aliased nodes, or if the user wishes
/// for only that particular node to be modified. As such, [AliasError] reflects
/// the detection that our change will impact an alias, and we do not intend
/// on supporting such changes for the foreseeable future.
class AliasError extends UnsupportedError {
/// The path that caused the error
final Iterable<Object> path;
/// The anchor node of the alias
final YamlNode anchor;
AliasError(this.path, this.anchor)
: super('Encountered an alias node along $path! '
'Alias nodes are nodes that refer to a previously serialized nodes, '
'and are denoted by either the "*" or the "&" indicators in the '
'original YAML. As the resulting behavior of mutations on these '
'nodes is not well-defined, the operation will not be supported '
'by this library.\n\n'
'${anchor.span.message('The alias was first defined here.')}');
/// Error thrown when an assertion about the YAML fails. Extends
/// [AssertionError] to override the [toString] method for pretty printing.
class _YamlAssertionError extends AssertionError {
_YamlAssertionError(message) : super(message);
String toString() {
if (message != null) {
return 'Assertion failed: $message';
return 'Assertion failed';
/// Throws an [AssertionError] with the given [message], and format
/// [oldYaml] and [newYaml] for information.
Error createAssertionError(String message, String oldYaml, String newYaml) {
return _YamlAssertionError('''
(package:yaml_edit) $message
# YAML before edit:
> ${oldYaml.replaceAll('\n', '\n> ')}
# YAML after edit:
> ${newYaml.replaceAll('\n', '\n> ')}
Please file an issue at: