| // Copyright (c) 2018, 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:json_annotation/json_annotation.dart'; |
| import 'package:yaml/yaml.dart'; |
| |
| ParsedYamlException parsedYamlException(String message, YamlNode yamlNode) => |
| new ParsedYamlException._(message, yamlNode); |
| |
| ParsedYamlException parsedYamlExceptionFromError( |
| CheckedFromJsonException error, StackTrace stack) { |
| var innerError = error.innerError; |
| if (innerError is BadKeyException) { |
| var map = innerError.map; |
| if (map is YamlMap) { |
| // if the associated key exists, use that as the error node, |
| // otherwise use the map itself |
| var node = map.nodes.keys.cast<YamlNode>().singleWhere((key) { |
| return key.value == innerError.key; |
| }, orElse: () => map); |
| |
| return new ParsedYamlException._(innerError.message, node, |
| innerError: error, innerStack: stack); |
| } |
| } else if (innerError is ParsedYamlException) { |
| return innerError; |
| } |
| |
| var yamlMap = error.map as YamlMap; |
| var yamlNode = yamlMap.nodes[error.key]; |
| |
| String message; |
| if (yamlNode == null) { |
| assert(error.message != null); |
| message = error.message; |
| yamlNode = yamlMap; |
| } else { |
| if (error.message == null) { |
| message = 'Unsupported value for `${error.key}`.'; |
| } else { |
| message = error.message.toString(); |
| } |
| } |
| |
| return new ParsedYamlException._(message, yamlNode, |
| innerError: error, innerStack: stack); |
| } |
| |
| /// Thrown when parsing a YAML document fails. |
| class ParsedYamlException implements Exception { |
| /// Describes the nature of the parse failure. |
| final String message; |
| |
| final YamlNode yamlNode; |
| |
| /// If this exception was thrown as a result of another error, |
| /// contains the source error object. |
| final Object innerError; |
| |
| /// If this exception was thrown as a result of another error, |
| /// contains the corresponding [StackTrace]. |
| final StackTrace innerStack; |
| |
| ParsedYamlException._(this.message, this.yamlNode, |
| {this.innerError, this.innerStack}); |
| |
| /// Returns [message] formatted with source information provided by |
| /// [yamlNode]. |
| String get formattedMessage => yamlNode.span.message(message); |
| |
| @override |
| String toString() => message; |
| } |
| |
| /// Package-private class representing an invalid key. |
| /// |
| /// Used instead of [CheckedFromJsonException] when highlighting a bad [key] |
| /// is desired, instead of the associated value. |
| class BadKeyException implements Exception { |
| final Map map; |
| final String key; |
| final String message; |
| |
| BadKeyException(this.map, this.key, this.message); |
| } |