| // 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. | |
| @sealed | |
| 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, | |
| super(message); | |
| @override | |
| 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'; | |
| } | |
| } | |
| /// Exception 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, [AliasException] reflects the | |
| /// detection that our change will impact an alias, and we do not intend on | |
| /// supporting such changes for the foreseeable future. | |
| @sealed | |
| class AliasException extends FormatException { | |
| /// The path that caused the error | |
| final Iterable<Object?> path; | |
| /// The anchor node of the alias | |
| final YamlNode anchor; | |
| AliasException(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(super.message); | |
| @override | |
| 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: | |
| https://github.com/dart-lang/yaml_edit/issues/new?labels=bug | |
| '''); | |
| } |