Skip to content

Commit 22f8b27

Browse files
committed
Improved throw error message in json_serializer
The throw error message now shows the type that it was expecting and the actual type that is having. Added another constructor in json_exceptiont that uses the json field type. Added enum_out_of_ranget exception class that inherits from std::out_of_range in enum_out_of_range.h. Added json_kind_out_of_ranget exception class in json_kind_out_of_range.h that extends enum_out_of_ranget, used for a better way of describing exceptions when a JSON kind field is not in the enum's possible values. Used json_kind_out_of_ranget exception class in json_exceptiont class.
1 parent 41cbe33 commit 22f8b27

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

src/util/enum_out_of_range.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module: enum_out_of_range
4+
5+
Author: Marius-Constantin Melemciuc
6+
7+
Purpose: Exception to report enums that are out of their
8+
expected range.
9+
10+
Date: April 2017
11+
12+
@ Copyright Diffblue, Ltd.
13+
14+
\*******************************************************************/
15+
16+
#ifndef CPROVER_UTIL_ENUM_OUT_OF_RANGE_H
17+
#define CPROVER_UTIL_ENUM_OUT_OF_RANGE_H
18+
19+
#include <stdexcept>
20+
21+
22+
/*******************************************************************\
23+
24+
Class: enum_out_of_ranget
25+
26+
Purpose: The type of exception thrown when an enum instance
27+
is out of the enum's range.
28+
29+
\*******************************************************************/
30+
class enum_out_of_ranget:public std::out_of_range
31+
{
32+
public:
33+
using std::out_of_range::out_of_range;
34+
};
35+
36+
#endif // CPROVER_UTIL_ENUM_OUT_OF_RANGE_H

src/util/json_kind_out_of_range.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*******************************************************************\
2+
3+
Module: json_kind_out_of_range
4+
5+
Author: Marius-Constantin Melemciuc
6+
7+
Purpose: Exception to report JSON kind that is out of the
8+
expected range.
9+
10+
Date: April 2017
11+
12+
@ Copyright Diffblue, Ltd.
13+
14+
\*******************************************************************/
15+
16+
#ifndef CPROVER_UTIL_JSON_KIND_OUT_OF_RANGE_H
17+
#define CPROVER_UTIL_JSON_KIND_OUT_OF_RANGE_H
18+
19+
#include "enum_out_of_range.h"
20+
21+
22+
/*******************************************************************\
23+
24+
Class: json_kind_out_of_ranget
25+
26+
Purpose: The type of exception thrown when the kind field of a JSON
27+
is not of a defined enum type.
28+
29+
\*******************************************************************/
30+
class json_kind_out_of_ranget:public enum_out_of_ranget
31+
{
32+
public:
33+
using enum_out_of_ranget::enum_out_of_ranget;
34+
35+
json_kind_out_of_ranget()
36+
: enum_out_of_ranget("Invalid jsont kind")
37+
{
38+
}
39+
};
40+
41+
#endif // CPROVER_UTIL_JSON_KIND_OUT_OF_RANGE_H

src/util/json_serializer.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ json_objectt json_serializert::load_json(
2222
if(parse_json(file_path, message_handler, json))
2323
throw json_exceptiont("Couldn't parse JSON");
2424
if(!json.is_object())
25-
throw json_exceptiont("JSON for serializaton wasn't an object");
25+
throw json_exceptiont(
26+
"Tried to read an object but JSON contained a {0}.",
27+
json);
2628
return static_cast<json_objectt &>(json);
2729
}
2830

@@ -141,7 +143,9 @@ void json_serializert::serialize_object(
141143
std::function<void(serializert &serializer)> serialize)
142144
{
143145
if(is_for_reading() && !json[name].is_object())
144-
throw json_exceptiont("JSON object was not an object");
146+
throw json_exceptiont(
147+
"Tried to read an object but JSON contained a {0}.",
148+
json[name]);
145149
json_serializert serializer(this, json[name].make_object(), is_for_reading());
146150
serialize(serializer);
147151
}
@@ -151,11 +155,15 @@ void json_serializert::read_array(
151155
std::function<void(serializert &serializer)> read_elt)
152156
{
153157
if(!json[name].is_array())
154-
throw json_exceptiont("JSON array was not an array");
158+
throw json_exceptiont(
159+
"Tried to read an array but JSON contained a {0}.",
160+
json[name]);
155161
for(jsont json_elt : json[name].array)
156162
{
157163
if(!json_elt.is_object())
158-
throw json_exceptiont("JSON object was not an object");
164+
throw json_exceptiont(
165+
"Tried to read an object but JSON contained a {0}.",
166+
json[name]);
159167
json_serializert serializer(this, json_elt.make_object(), is_for_reading());
160168
read_elt(serializer);
161169
}

src/util/json_serializer.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ Purpose: Generic serialization of object hierarchies to JSON.
1111
#ifndef CPROVER_UTIL_JSON_SERIALIZER_H
1212
#define CPROVER_UTIL_JSON_SERIALIZER_H
1313

14+
#include "json_kind_out_of_range.h"
15+
1416
#include <util/serializer.h>
1517
#include <util/json.h>
1618
#include <util/message.h>
1719
#include <json/json_parser.h>
20+
21+
#include <boost/algorithm/string/replace.hpp>
22+
1823
#include <fstream>
1924
#include <algorithm>
2025

@@ -40,6 +45,35 @@ class json_exceptiont:public std::runtime_error
4045
: std::runtime_error(what_arg)
4146
{
4247
}
48+
49+
json_exceptiont(std::string what_arg, const jsont &json)
50+
: std::runtime_error(construct_error_message(std::move(what_arg), json))
51+
{
52+
}
53+
54+
private:
55+
static std::string format_jsont(const jsont &json)
56+
{
57+
switch(json.kind)
58+
{
59+
case jsont::J_STRING: return "string (" + json.value + ")";
60+
case jsont::J_NUMBER: return "number (" + json.value + ")";
61+
case jsont::J_OBJECT: return "object";
62+
case jsont::J_ARRAY: return "array";
63+
case jsont::J_TRUE: return "bool (true)";
64+
case jsont::J_FALSE: return "bool (false)";
65+
case jsont::J_NULL: return "null";
66+
default: throw json_kind_out_of_ranget();
67+
}
68+
}
69+
70+
std::string construct_error_message(
71+
std::string error_message,
72+
const jsont &json)
73+
{
74+
boost::replace_all(error_message, "{0}", format_jsont(json));
75+
return error_message;
76+
}
4377
};
4478

4579
/*******************************************************************\

0 commit comments

Comments
 (0)