@@ -171,16 +171,17 @@ void SetOptionalField(nlohmann::json& json, std::string_view key,
171171 }
172172}
173173
174- std::string DumpJsonNoExcept (const nlohmann::json& json) {
175- return json.dump (-1 , ' ' , false , nlohmann::detail::error_handler_t ::ignore);
174+ std::string SafeDumpJson (const nlohmann::json& json) {
175+ return json.dump (/* indent=*/ -1 , /* indent_char=*/ ' ' , /* ensure_ascii=*/ false ,
176+ nlohmann::detail::error_handler_t ::ignore);
176177}
177178
178179template <typename T>
179180Result<T> GetJsonValueImpl (const nlohmann::json& json, std::string_view key) {
180181 try {
181182 return json.at (key).get <T>();
182183 } catch (const std::exception& ex) {
183- return JsonParseError (" Failed to parse '{}' from {}: {}" , key, DumpJsonNoExcept (json),
184+ return JsonParseError (" Failed to parse '{}' from {}: {}" , key, SafeDumpJson (json),
184185 ex.what ());
185186 }
186187}
@@ -197,7 +198,7 @@ Result<std::optional<T>> GetJsonValueOptional(const nlohmann::json& json,
197198template <typename T>
198199Result<T> GetJsonValue (const nlohmann::json& json, std::string_view key) {
199200 if (!json.contains (key)) {
200- return JsonParseError (" Missing '{}' in {}" , key, DumpJsonNoExcept (json));
201+ return JsonParseError (" Missing '{}' in {}" , key, SafeDumpJson (json));
201202 }
202203 return GetJsonValueImpl<T>(json, key);
203204}
@@ -248,7 +249,7 @@ Result<std::vector<T>> FromJsonList(
248249 ICEBERG_ASSIGN_OR_RAISE (auto list_json, GetJsonValue<nlohmann::json>(json, key));
249250 if (!list_json.is_array ()) {
250251 return JsonParseError (" Cannot parse '{}' from non-array: {}" , key,
251- DumpJsonNoExcept (list_json));
252+ SafeDumpJson (list_json));
252253 }
253254 for (const auto & entry_json : list_json) {
254255 ICEBERG_ASSIGN_OR_RAISE (auto entry, from_json (entry_json));
@@ -273,7 +274,7 @@ Result<std::vector<std::shared_ptr<T>>> FromJsonList(
273274 ICEBERG_ASSIGN_OR_RAISE (auto list_json, GetJsonValue<nlohmann::json>(json, key));
274275 if (!list_json.is_array ()) {
275276 return JsonParseError (" Cannot parse '{}' from non-array: {}" , key,
276- DumpJsonNoExcept (list_json));
277+ SafeDumpJson (list_json));
277278 }
278279 for (const auto & entry_json : list_json) {
279280 ICEBERG_ASSIGN_OR_RAISE (auto entry, from_json (entry_json));
@@ -322,16 +323,16 @@ Result<std::unordered_map<std::string, T>> FromJsonMap(
322323 try {
323324 return json.get <std::string>();
324325 } catch (const std::exception& ex) {
325- return JsonParseError (" Cannot parse {} to a string value: {}" ,
326- DumpJsonNoExcept (json), ex.what ());
326+ return JsonParseError (" Cannot parse {} to a string value: {}" , SafeDumpJson (json),
327+ ex.what ());
327328 }
328329 }) {
329330 std::unordered_map<std::string, T> map{};
330331 if (json.contains (key)) {
331332 ICEBERG_ASSIGN_OR_RAISE (auto map_json, GetJsonValue<nlohmann::json>(json, key));
332333 if (!map_json.is_object ()) {
333334 return JsonParseError (" Cannot parse '{}' from non-object: {}" , key,
334- DumpJsonNoExcept (map_json));
335+ SafeDumpJson (map_json));
335336 }
336337 for (const auto & [key, value] : map_json.items ()) {
337338 ICEBERG_ASSIGN_OR_RAISE (auto entry, from_json (value));
@@ -636,8 +637,7 @@ Result<std::unique_ptr<Schema>> SchemaFromJson(const nlohmann::json& json) {
636637 ICEBERG_ASSIGN_OR_RAISE (auto type, TypeFromJson (json));
637638
638639 if (type->type_id () != TypeId::kStruct ) [[unlikely]] {
639- return JsonParseError (" Schema must be a struct type, but got {}" ,
640- DumpJsonNoExcept (json));
640+ return JsonParseError (" Schema must be a struct type, but got {}" , SafeDumpJson (json));
641641 }
642642
643643 auto & struct_type = static_cast <StructType&>(*type);
@@ -746,11 +746,11 @@ Result<std::unique_ptr<Snapshot>> SnapshotFromJson(const nlohmann::json& json) {
746746 }
747747 if (!value.is_string ()) {
748748 return JsonParseError (" Invalid snapshot summary field value: {}" ,
749- DumpJsonNoExcept (value));
749+ SafeDumpJson (value));
750750 }
751751 if (key == SnapshotSummaryFields::kOperation &&
752752 !kValidDataOperation .contains (value.get <std::string>())) {
753- return JsonParseError (" Invalid snapshot operation: {}" , DumpJsonNoExcept (value));
753+ return JsonParseError (" Invalid snapshot operation: {}" , SafeDumpJson (value));
754754 }
755755 summary[key] = value.get <std::string>();
756756 }
@@ -980,7 +980,7 @@ Result<std::shared_ptr<Schema>> ParseSchemas(
980980 GetJsonValue<nlohmann::json>(json, kSchemas ));
981981 if (!schema_array.is_array ()) {
982982 return JsonParseError (" Cannot parse schemas from non-array: {}" ,
983- DumpJsonNoExcept (schema_array));
983+ SafeDumpJson (schema_array));
984984 }
985985
986986 ICEBERG_ASSIGN_OR_RAISE (current_schema_id,
@@ -995,7 +995,7 @@ Result<std::shared_ptr<Schema>> ParseSchemas(
995995 }
996996 if (!current_schema) {
997997 return JsonParseError (" Cannot find schema with {}={} from {}" , kCurrentSchemaId ,
998- current_schema_id.value (), DumpJsonNoExcept (schema_array));
998+ current_schema_id.value (), SafeDumpJson (schema_array));
999999 }
10001000 } else {
10011001 if (format_version != 1 ) {
@@ -1026,7 +1026,7 @@ Status ParsePartitionSpecs(const nlohmann::json& json, int8_t format_version,
10261026 GetJsonValue<nlohmann::json>(json, kPartitionSpecs ));
10271027 if (!spec_array.is_array ()) {
10281028 return JsonParseError (" Cannot parse partition specs from non-array: {}" ,
1029- DumpJsonNoExcept (spec_array));
1029+ SafeDumpJson (spec_array));
10301030 }
10311031 ICEBERG_ASSIGN_OR_RAISE (default_spec_id, GetJsonValue<int32_t >(json, kDefaultSpecId ));
10321032
@@ -1045,7 +1045,7 @@ Status ParsePartitionSpecs(const nlohmann::json& json, int8_t format_version,
10451045 GetJsonValue<nlohmann::json>(json, kPartitionSpec ));
10461046 if (!partition_spec_json.is_array ()) {
10471047 return JsonParseError (" Cannot parse v1 partition spec from non-array: {}" ,
1048- DumpJsonNoExcept (partition_spec_json));
1048+ SafeDumpJson (partition_spec_json));
10491049 }
10501050
10511051 int32_t next_partition_field_id = PartitionSpec::kLegacyPartitionDataIdStart ;
@@ -1104,7 +1104,7 @@ Status ParseSortOrders(const nlohmann::json& json, int8_t format_version,
11041104Result<std::unique_ptr<TableMetadata>> TableMetadataFromJson (const nlohmann::json& json) {
11051105 if (!json.is_object ()) {
11061106 return JsonParseError (" Cannot parse metadata from a non-object: {}" ,
1107- DumpJsonNoExcept (json));
1107+ SafeDumpJson (json));
11081108 }
11091109
11101110 auto table_metadata = std::make_unique<TableMetadata>();
@@ -1216,8 +1216,9 @@ Result<std::unique_ptr<TableMetadata>> TableMetadataFromJson(const nlohmann::jso
12161216}
12171217
12181218Result<nlohmann::json> FromJsonString (const std::string& json_string) {
1219- auto json = nlohmann::json::parse (json_string, nullptr , false );
1220- if (json.is_discarded ()) {
1219+ auto json =
1220+ nlohmann::json::parse (json_string, /* cb=*/ nullptr , /* allow_exceptions=*/ false );
1221+ if (json.is_discarded ()) [[unlikely]] {
12211222 return JsonParseError (" Failed to parse JSON string: {}" , json_string);
12221223 }
12231224 return json;
0 commit comments