blob: 04c54d871cd36e556f9a95c3177f2ec38f714e4e [file] [log] [blame]
// 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');
}