1 /* Copyright (c) 2009 Nicira Networks
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include "ovsdb-error.h"
22 #include "backtrace.h"
23 #include "dynamic-string.h"
28 const char *tag; /* String for "error" member. */
29 char *details; /* String for "details" member. */
30 char *syntax; /* String for "syntax" member. */
31 int errno_; /* Unix errno value, 0 if none. */
34 static struct ovsdb_error *
35 ovsdb_error_valist(const char *tag, const char *details, va_list args)
37 struct ovsdb_error *error = xmalloc(sizeof *error);
38 error->tag = tag ? tag : "ovsdb error";
39 error->details = details ? xvasprintf(details, args) : NULL;
46 ovsdb_error(const char *tag, const char *details, ...)
48 struct ovsdb_error *error;
51 va_start(args, details);
52 error = ovsdb_error_valist(tag, details, args);
59 ovsdb_io_error(int errno_, const char *details, ...)
61 struct ovsdb_error *error;
64 va_start(args, details);
65 error = ovsdb_error_valist("I/O error", details, args);
68 error->errno_ = errno_;
74 ovsdb_syntax_error(const struct json *json, const char *tag,
75 const char *details, ...)
77 struct ovsdb_error *error;
80 va_start(args, details);
81 error = ovsdb_error_valist(tag ? tag : "syntax error", details, args);
85 /* XXX this is much too much information in some cases */
86 error->syntax = json_to_string(json, 0);
93 ovsdb_wrap_error(struct ovsdb_error *error, const char *details, ...)
98 va_start(args, details);
99 msg = xvasprintf(details, args);
102 if (error->details) {
103 char *new = xasprintf("%s: %s", msg, error->details);
104 free(error->details);
105 error->details = new;
108 error->details = msg;
115 ovsdb_internal_error(const char *file, int line, const char *details, ...)
117 struct ds ds = DS_EMPTY_INITIALIZER;
118 struct backtrace backtrace;
119 struct ovsdb_error *error;
122 ds_put_format(&ds, "%s:%d:", file, line);
125 ds_put_char(&ds, ' ');
126 va_start(args, details);
127 ds_put_format_valist(&ds, details, args);
131 backtrace_capture(&backtrace);
132 if (backtrace.n_frames) {
135 ds_put_cstr(&ds, " (backtrace:");
136 for (i = 0; i < backtrace.n_frames; i++) {
137 ds_put_format(&ds, " 0x%08"PRIxPTR, backtrace.frames[i]);
139 ds_put_char(&ds, ')');
142 ds_put_format(&ds, " (%s %s%s)", program_name, VERSION, BUILDNR);
144 error = ovsdb_error("internal error", "%s", ds_cstr(&ds));
152 ovsdb_error_destroy(struct ovsdb_error *error)
155 free(error->details);
162 ovsdb_error_clone(const struct ovsdb_error *old)
165 struct ovsdb_error *new = xmalloc(sizeof *new);
167 new->details = old->details ? xstrdup(old->details) : NULL;
168 new->syntax = old->syntax ? xstrdup(old->syntax) : NULL;
169 new->errno_ = old->errno_;
177 ovsdb_errno_string(int error)
179 return error == EOF ? "unexpected end of file" : strerror(error);
183 ovsdb_error_to_json(const struct ovsdb_error *error)
185 struct json *json = json_object_create();
186 json_object_put_string(json, "error", error->tag);
187 if (error->details) {
188 json_object_put_string(json, "details", error->details);
191 json_object_put_string(json, "syntax", error->syntax);
194 json_object_put_string(json, "io-error",
195 ovsdb_errno_string(error->errno_));
201 ovsdb_error_to_string(const struct ovsdb_error *error)
203 struct ds ds = DS_EMPTY_INITIALIZER;
205 ds_put_format(&ds, "syntax \"%s\": ", error->syntax);
207 ds_put_cstr(&ds, error->tag);
208 if (error->details) {
209 ds_put_format(&ds, ": %s", error->details);
212 ds_put_format(&ds, " (%s)", ovsdb_errno_string(error->errno_));
214 return ds_steal_cstr(&ds);
218 ovsdb_error_get_tag(const struct ovsdb_error *error)