@@ -202,6 +202,69 @@ absl::StatusOr<Error> SetIncompatibleSchemaError(
202202 return cause;
203203}
204204
205+ constexpr const char * kDataBagMergeErrorSchemaConflict =
206+ " cannot merge DataBags due to an exception encountered when merging "
207+ " schemas.\n\n "
208+ " The conflicting schema in the first DataBag: %s\n "
209+ " The conflicting schema in the second DataBag: %s\n\n "
210+ " The cause is the schema for attribute %s is incompatible: %s vs %s\n " ;
211+
212+ constexpr const char * kDataBagMergeErrorDictConflict =
213+ " cannot merge DataBags due to an exception encountered when merging "
214+ " dicts.\n\n "
215+ " The conflicting dict in the first DataBag: %s\n "
216+ " The conflicting dict in the second DataBag: %s\n\n "
217+ " The cause is the value of the key %s is incompatible: %s vs %s\n " ;
218+
219+ absl::StatusOr<Error> SetDataBagMergeError (Error cause, const DataBagPtr& db1,
220+ const DataBagPtr& db2) {
221+ const auto & schema_or_dict_conflict = cause.schema_or_dict_conflict ();
222+ ASSIGN_OR_RETURN (
223+ internal::DataItem object_item,
224+ DecodeDataItem (schema_or_dict_conflict.object_id ()));
225+ ASSIGN_OR_RETURN (internal::DataItem key_item,
226+ DecodeDataItem (schema_or_dict_conflict.key ()));
227+ internal::DataItem schema = internal::DataItem (
228+ object_item.is_schema () ? schema::kSchema : schema::kAny );
229+ ASSIGN_OR_RETURN (
230+ DataSlice expected_value,
231+ DataSlice::Create (
232+ DecodeDataItem (schema_or_dict_conflict.expected_value ()),
233+ DataSlice::JaggedShape::Empty (), schema,
234+ db1));
235+ ASSIGN_OR_RETURN (
236+ DataSlice assigned_value,
237+ DataSlice::Create (
238+ DecodeDataItem (schema_or_dict_conflict.assigned_value ()),
239+ DataSlice::JaggedShape::Empty (), schema,
240+ db2));
241+ ASSIGN_OR_RETURN (
242+ DataSlice item,
243+ DataSlice::Create (object_item, schema, db1));
244+ ASSIGN_OR_RETURN (
245+ DataSlice conflicting_item,
246+ DataSlice::Create (object_item, std::move (schema), db2));
247+
248+ std::string key_str = internal::DataItemRepr (
249+ key_item, {.strip_quotes = false });
250+ ASSIGN_OR_RETURN (std::string item_str, DataSliceToStr (item));
251+ ASSIGN_OR_RETURN (std::string conflicting_item_str,
252+ DataSliceToStr (conflicting_item));
253+ ASSIGN_OR_RETURN (std::string expected_value_str,
254+ DataSliceToStr (expected_value));
255+ ASSIGN_OR_RETURN (std::string assigned_value_str,
256+ DataSliceToStr (assigned_value));
257+ std::string error_str =
258+ object_item.is_schema ()
259+ ? absl::StrFormat (kDataBagMergeErrorSchemaConflict , item_str,
260+ conflicting_item_str, key_str, expected_value_str,
261+ assigned_value_str)
262+ : absl::StrFormat (kDataBagMergeErrorDictConflict , item_str,
263+ conflicting_item_str, key_str, expected_value_str,
264+ assigned_value_str);
265+ cause.set_error_message (std::move (error_str));
266+ return cause;
267+ }
205268} // namespace
206269
207270absl::Status AssembleErrorMessage (const absl::Status& status,
@@ -225,6 +288,12 @@ absl::Status AssembleErrorMessage(const absl::Status& status,
225288 data.db , data.ds ));
226289 return WithErrorPayload (status, error);
227290 }
291+ if (cause->has_schema_or_dict_conflict ()) {
292+ ASSIGN_OR_RETURN (Error error,
293+ SetDataBagMergeError (*std::move (cause), data.db ,
294+ data.to_be_merged_db ));
295+ return WithErrorPayload (status, error);
296+ }
228297 return status;
229298}
230299
0 commit comments