-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return error;
}
+/* Returns an ovsdb_error that represents an internal error for file name
+ * 'file' and line number 'line', with 'details' (formatted as with printf())
+ * as the associated message. The caller is responsible for freeing the
+ * returned error.
+ *
+ * If 'inner_error' is nonnull then the returned error is wrapped around
+ * 'inner_error'. Takes ownership of 'inner_error'. */
struct ovsdb_error *
-ovsdb_internal_error(const char *file, int line, const char *details, ...)
+ovsdb_internal_error(struct ovsdb_error *inner_error,
+ const char *file, int line, const char *details, ...)
{
struct ds ds = DS_EMPTY_INITIALIZER;
struct backtrace backtrace;
ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR);
+ if (inner_error) {
+ char *s = ovsdb_error_to_string(inner_error);
+ ds_put_format(&ds, " (generated from: %s)", s);
+ free(s);
+
+ ovsdb_error_destroy(inner_error);
+ }
+
error = ovsdb_error("internal error", "%s", ds_cstr(&ds));
ds_destroy(&ds);
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
const char *details, ...)
PRINTF_FORMAT(2, 3);
-struct ovsdb_error *ovsdb_internal_error(const char *file, int line,
+struct ovsdb_error *ovsdb_internal_error(struct ovsdb_error *error,
+ const char *file, int line,
const char *details, ...)
- PRINTF_FORMAT(3, 4)
+ PRINTF_FORMAT(4, 5)
WARN_UNUSED_RESULT;
-#define OVSDB_BUG(MSG) ovsdb_internal_error(__FILE__, __LINE__, "%s", MSG)
+
+/* Returns a pointer to an ovsdb_error that represents an internal error for
+ * the current file name and line number with MSG as the associated message.
+ * The caller is responsible for freeing the internal error. */
+#define OVSDB_BUG(MSG) \
+ ovsdb_internal_error(NULL, __FILE__, __LINE__, "%s", MSG)
+
+/* Returns a pointer to an ovsdb_error that represents an internal error for
+ * the current file name and line number, with MSG as the associated message.
+ * If ERROR is nonnull then the internal error is wrapped around ERROR. Takes
+ * ownership of ERROR. The caller is responsible for freeing the returned
+ * error. */
+#define OVSDB_WRAP_BUG(MSG, ERROR) \
+ ovsdb_internal_error(ERROR, __FILE__, __LINE__, "%s", MSG)
void ovsdb_error_destroy(struct ovsdb_error *);
struct ovsdb_error *ovsdb_error_clone(const struct ovsdb_error *)
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if (r->old) {
error = ovsdb_txn_adjust_row_refs(txn, r->old, column, -1);
if (error) {
- ovsdb_error_destroy(error);
- return OVSDB_BUG("error decreasing refcount");
+ return OVSDB_WRAP_BUG("error decreasing refcount", error);
}
}
if (r->new) {
* was really a no-op. */
error = for_each_txn_row(txn, determine_changes);
if (error) {
- ovsdb_error_destroy(error);
- return OVSDB_BUG("can't happen");
+ return OVSDB_WRAP_BUG("can't happen", error);
}
if (list_is_empty(&txn->txn_tables)) {
ovsdb_txn_abort(txn);