| // 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 'allowed_keys_helpers.dart'; |
| |
| /// Helper function used in generated code when |
| /// `JsonSerializableGenerator.checked` is `true`. |
| /// |
| /// Should not be used directly. |
| T $checkedCreate<T>( |
| String className, |
| Map map, |
| T Function( |
| S Function<S>( |
| String, |
| S Function(Object?), { |
| Object? Function(Map, String)? readValue, |
| }), |
| ) constructor, { |
| Map<String, String> fieldKeyMap = const {}, |
| }) { |
| Q checkedConvert<Q>( |
| String key, |
| Q Function(Object?) convertFunction, { |
| Object? Function(Map, String)? readValue, |
| }) => |
| $checkedConvert<Q>(map, key, convertFunction, readValue: readValue); |
| |
| return $checkedNew( |
| className, |
| map, |
| () => constructor(checkedConvert), |
| fieldKeyMap: fieldKeyMap, |
| ); |
| } |
| |
| /// Helper function used in generated code when |
| /// `JsonSerializableGenerator.checked` is `true`. |
| /// |
| /// Should not be used directly. |
| T $checkedNew<T>( |
| String className, |
| Map map, |
| T Function() constructor, { |
| Map<String, String>? fieldKeyMap, |
| }) { |
| fieldKeyMap ??= const {}; |
| |
| try { |
| return constructor(); |
| } on CheckedFromJsonException catch (e) { |
| if (identical(e.map, map) && e._className == null) { |
| e._className = className; |
| } |
| rethrow; |
| } catch (error, stack) { |
| String? key; |
| if (error is ArgumentError) { |
| key = fieldKeyMap[error.name] ?? error.name; |
| } else if (error is MissingRequiredKeysException) { |
| key = error.missingKeys.first; |
| } else if (error is DisallowedNullValueException) { |
| key = error.keysWithNullValues.first; |
| } |
| throw CheckedFromJsonException._( |
| error, |
| stack, |
| map, |
| key, |
| className: className, |
| ); |
| } |
| } |
| |
| /// Helper function used in generated code when |
| /// `JsonSerializableGenerator.checked` is `true`. |
| /// |
| /// Should not be used directly. |
| T $checkedConvert<T>( |
| Map map, |
| String key, |
| T Function(dynamic) castFunc, { |
| Object? Function(Map, String)? readValue, |
| }) { |
| try { |
| return castFunc(readValue == null ? map[key] : readValue(map, key)); |
| } on CheckedFromJsonException { |
| rethrow; |
| } catch (error, stack) { |
| throw CheckedFromJsonException._(error, stack, map, key); |
| } |
| } |
| |
| /// Exception thrown if there is a runtime exception in `fromJson` |
| /// code generated when `JsonSerializableGenerator.checked` is `true` |
| class CheckedFromJsonException implements Exception { |
| /// The [Error] or [Exception] that triggered this exception. |
| /// |
| /// If this instance was created by user code, this field will be `null`. |
| final Object? innerError; |
| |
| /// The [StackTrace] for the [Error] or [Exception] that triggered this |
| /// exception. |
| /// |
| /// If this instance was created by user code, this field will be `null`. |
| final StackTrace? innerStack; |
| |
| /// The key from [map] that corresponds to the thrown [innerError]. |
| /// |
| /// May be `null`. |
| final String? key; |
| |
| /// The source [Map] that was used for decoding when the [innerError] was |
| /// thrown. |
| final Map map; |
| |
| /// A human-readable message corresponding to [innerError]. |
| /// |
| /// May be `null`. |
| final String? message; |
| |
| /// The name of the class being created when [innerError] was thrown. |
| String? get className => _className; |
| String? _className; |
| |
| /// If this was thrown due to an invalid or unsupported key, as opposed to an |
| /// invalid value. |
| final bool badKey; |
| |
| /// Creates a new instance of [CheckedFromJsonException]. |
| CheckedFromJsonException( |
| this.map, |
| this.key, |
| String className, |
| this.message, { |
| this.badKey = false, |
| }) : _className = className, |
| innerError = null, |
| innerStack = null; |
| |
| CheckedFromJsonException._( |
| Object this.innerError, |
| this.innerStack, |
| this.map, |
| this.key, { |
| String? className, |
| }) : _className = className, |
| badKey = innerError is BadKeyException, |
| message = _getMessage(innerError); |
| |
| static String _getMessage(Object error) { |
| if (error is ArgumentError) { |
| final message = error.message; |
| if (message != null) { |
| return message.toString(); |
| } |
| } |
| if (error is BadKeyException) { |
| return error.message; |
| } |
| if (error is FormatException) { |
| var message = error.message; |
| if (error.offset != null) { |
| message = '$message at offset ${error.offset}.'; |
| } |
| return message; |
| } |
| return error.toString(); |
| } |
| |
| @override |
| String toString() => <String>[ |
| 'CheckedFromJsonException', |
| if (_className != null) 'Could not create `$_className`.', |
| if (key != null) 'There is a problem with "$key".', |
| if (message != null) |
| message! |
| else if (innerError != null) |
| innerError.toString(), |
| ].join('\n'); |
| } |