@@ -74,22 +74,31 @@ bool confirmation_callback_t::is_error() const {
74
74
75
75
namespace {
76
76
77
- std::vector<error_detail> find_errors_in_array (const std::string& obj, size_t index, const std::string& current_field, json::iterator begin, json::iterator end) {
77
+ std::vector<error_detail> find_errors_in_array (const std::string& obj, int index, const std::string& current_field, const json &j);
78
+
79
+ std::vector<error_detail> find_errors_in_object (const std::string& obj, int index, const std::string& current_field, const json &j) {
78
80
std::vector<error_detail> ret;
79
81
80
- for (auto it = begin; it != end; ++it) {
81
- if (auto errors = it->find (" _errors" ); errors != it->end ()) {
82
- for (auto errordetails = errors->begin (); errordetails != errors->end (); ++errordetails) {
83
- error_detail detail;
84
- detail.code = (*errordetails)[" code" ].get <std::string>();
85
- detail.reason = (*errordetails)[" message" ].get <std::string>();
86
- detail.field = current_field + it.key ();
87
- detail.object = obj;
88
- detail.index = index ;
89
- ret.emplace_back (detail);
82
+ if (auto errors = j.find (" _errors" ); errors != j.end ()) {
83
+ for (auto errordetails = errors->begin (); errordetails != errors->end (); ++errordetails) {
84
+ error_detail detail;
85
+ detail.code = (*errordetails)[" code" ].get <std::string>();
86
+ detail.reason = (*errordetails)[" message" ].get <std::string>();
87
+ detail.field = current_field;
88
+ detail.object = obj;
89
+ detail.index = index ;
90
+ ret.emplace_back (detail);
91
+ }
92
+ } else {
93
+ for (auto it = j.begin (); it != j.end (); ++it) {
94
+ std::vector<error_detail> sub_errors;
95
+ std::string field = obj.empty () ? current_field : obj + ' .' + current_field;
96
+
97
+ if (it->is_array ()) {
98
+ sub_errors = find_errors_in_array (field, index , it.key (), *it);
99
+ } else {
100
+ sub_errors = find_errors_in_object (field, index , it.key (), *it);
90
101
}
91
- } else { // subobject has errors
92
- auto sub_errors = find_errors_in_array (obj, index , current_field + it.key () + " ." , it->begin (), it->end ());
93
102
94
103
if (!sub_errors.empty ()) {
95
104
ret.reserve (ret.capacity () + sub_errors.size ());
@@ -100,6 +109,30 @@ std::vector<error_detail> find_errors_in_array(const std::string& obj, size_t in
100
109
return ret;
101
110
}
102
111
112
+ std::vector<error_detail> find_errors_in_array (const std::string& obj, int index, const std::string& current_field, const json &j) {
113
+ std::vector<error_detail> ret;
114
+ int idx = 0 ;
115
+
116
+ for (auto it = j.begin (); it != j.end (); ++it) {
117
+ std::vector<error_detail> sub_errors;
118
+ std::string key = ' [' + std::to_string (idx) + ' ]' ;
119
+ std::string field = obj.empty () ? current_field : obj + ' .' + current_field;
120
+
121
+ if (it->is_array ()) {
122
+ sub_errors = find_errors_in_array (field, index , key, *it);
123
+ } else {
124
+ sub_errors = find_errors_in_object (field, index , key, *it);
125
+ }
126
+
127
+ if (!sub_errors.empty ()) {
128
+ ret.reserve (ret.capacity () + sub_errors.size ());
129
+ std::move (sub_errors.begin (), sub_errors.end (), std::back_inserter (ret));
130
+ }
131
+ ++idx;
132
+ }
133
+ return ret;
134
+ }
135
+
103
136
}
104
137
105
138
error_info confirmation_callback_t::get_error () const {
@@ -158,29 +191,18 @@ error_info confirmation_callback_t::get_error() const {
158
191
}
159
192
}
160
193
}
194
+ } else {
195
+ std::vector<error_detail> sub_errors;
161
196
162
- } else if (obj->find (" _errors" ) != obj->end ()) {
163
- /* An object of error messages (rare) */
164
- e.errors .reserve ((*obj)[" _errors" ].size ());
165
- for (auto errordetails = (*obj)[" _errors" ].begin (); errordetails != (*obj)[" _errors" ].end (); ++errordetails) {
166
- error_detail detail;
167
- detail.code = (*errordetails)[" code" ].get <std::string>();
168
- detail.reason = (*errordetails)[" message" ].get <std::string>();
169
- detail.object .clear ();
170
- detail.field = obj.key ();
171
- detail.index = 0 ;
172
- e.errors .emplace_back (detail);
197
+ if (obj->is_array ()) {
198
+ sub_errors = find_errors_in_array ({}, -1 , obj.key (), *obj);
199
+ } else {
200
+ sub_errors = find_errors_in_object ({}, -1 , obj.key (), *obj);
173
201
}
174
- } else {
175
- /* An object that has a subobject with errors */
176
- for (auto index = obj->begin (); index != obj->end (); ++index ) {
177
- int array_index = std::atoll (index .key ().c_str ());
178
- auto sub_errors = find_errors_in_array (obj.key (), array_index, {}, index ->begin (), index ->end ());
179
202
180
- if (!sub_errors.empty ()) {
181
- e.errors .reserve (e.errors .capacity () + sub_errors.size ());
182
- std::move (sub_errors.begin (), sub_errors.end (), std::back_inserter (e.errors ));
183
- }
203
+ if (!sub_errors.empty ()) {
204
+ e.errors .reserve (e.errors .capacity () + sub_errors.size ());
205
+ std::move (sub_errors.begin (), sub_errors.end (), std::back_inserter (e.errors ));
184
206
}
185
207
}
186
208
}
@@ -194,6 +216,9 @@ error_info confirmation_callback_t::get_error() const {
194
216
} else if (isdigit (*(error.object .c_str ()))) {
195
217
/* An unnamed array of objects where one or more generated an error, e.g. slash command bulk registration */
196
218
e.human_readable += prefix + " - <array>[" + error.object + " ]." + error.field + " : " + error.reason + " (" + error.code + " )" ;
219
+ } else if (error.index < 0 ) {
220
+ /* An object field that caused an error */
221
+ e.human_readable += prefix + " - " + error.object + ' .' + error.field + " : " + error.reason + " (" + error.code + " )" ;
197
222
} else {
198
223
/* A named array of objects whre a field in the object has an error */
199
224
e.human_readable += prefix + " - " + error.object + " [" + std::to_string (error.index ) + " ]." + error.field + " : " + error.reason + " (" + error.code + " )" ;
0 commit comments