All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_error.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2015 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_status.h>
20 
21 #include <stdarg.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /******************************************************************************
31  * MACROS
32  *****************************************************************************/
33 
34 /**
35  * The size of as_error.message
36  *
37  * @ingroup as_error_object
38  */
39 #define AS_ERROR_MESSAGE_MAX_SIZE 1024
40 
41 /**
42  * The maximum string length of as_error.message
43  *
44  * @ingroup as_error_object
45  */
46 #define AS_ERROR_MESSAGE_MAX_LEN (AS_ERROR_MESSAGE_MAX_SIZE - 1)
47 
48 /******************************************************************************
49  * TYPES
50  *****************************************************************************/
51 
52 /**
53  * All operations that interact with the Aerospike cluster accept an as_error
54  * argument and return an as_status value. The as_error argument is populated
55  * with information about the error that occurred. The as_status return value
56  * is the as_error.code value.
57  *
58  * When an operation succeeds, the as_error.code value is usually set to
59  * `AEROSPIKE_OK`. There are some operations which may have other success
60  * status codes, so please review each operation for information on status
61  * codes.
62  *
63  * When as_error.code is not a success value (`AEROSPIKE_OK`), then you can
64  * expect the other fields of as_error.code to be populated.
65  *
66  * Example usage:
67  * ~~~~~~~~~~{.c}
68  * as_error err;
69  *
70  * if ( aerospike_key_get(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK ) {
71  * fprintf(stderr, "(%d) %s at %s[%s:%d]\n", error.code, err.message, err.func, err.file. err.line);
72  * }
73  * ~~~~~~~~~~
74  *
75  * You can reuse an as_error with multiple operations. Each operation
76  * internally resets the error. So, if an error occurred in one operation,
77  * and you did not check it, then the error will be lost with subsequent
78  * operations.
79  *
80  * Example usage:
81  *
82  * ~~~~~~~~~~{.c}
83  * as_error err;
84  *
85  * if ( aerospike_key_put(&as, &err, NULL, &key, rec) != AEROSPIKE_OK ) {
86  * fprintf(stderr, "(%d) %s at %s[%s:%d]\n", error.code, err.message, err.func, err.file. err.line);
87  * }
88  *
89  * if ( aerospike_key_get(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK ) {
90  * fprintf(stderr, "(%d) %s at %s[%s:%d]\n", error.code, err.message, err.func, err.file. err.line);
91  * }
92  * ~~~~~~~~~~
93  *
94  * @ingroup client_objects
95  */
96 typedef struct as_error_s {
97 
98  /**
99  * Numeric error code
100  */
102 
103  /**
104  * NULL-terminated error message
105  */
107 
108  /**
109  * Name of the function where the error occurred.
110  */
111  const char * func;
112 
113  /**
114  * Name of the file where the error occurred.
115  */
116  const char * file;
117 
118  /**
119  * Line in the file where the error occurred.
120  */
121  uint32_t line;
122 
123 } as_error;
124 
125 /******************************************************************************
126  * MACROS
127  *****************************************************************************/
128 
129 /**
130  * as_error_update(&as->error, AEROSPIKE_OK, "%s %d", "a", 1);
131  *
132  * @ingroup as_error_object
133  */
134 #define as_error_update(__err, __code, __fmt, ...) \
135  as_error_setallv( __err, __code, __func__, __FILE__, __LINE__, __fmt, ##__VA_ARGS__ );
136 
137 /**
138  * as_error_set_message(&as->error, AEROSPIKE_ERR, "error message");
139  *
140  * @ingroup as_error_object
141  */
142 #define as_error_set_message(__err, __code, __msg) \
143  as_error_setall( __err, __code, __msg, __func__, __FILE__, __LINE__ );
144 
145 /******************************************************************************
146  * FUNCTIONS
147  *****************************************************************************/
148 
149 /**
150  * Initialize the error to default (empty) values, returning the error.
151  *
152  * @param err The error to initialize.
153  *
154  * @returns The initialized err.
155  *
156  * @relates as_error
157  * @ingroup as_error_object
158  */
159 static inline as_error * as_error_init(as_error * err) {
160  err->code = AEROSPIKE_OK;
161  err->message[0] = '\0';
162  err->func = NULL;
163  err->file = NULL;
164  err->line = 0;
165  return err;
166 }
167 
168 /**
169  * Resets the error to default (empty) values, returning the status code.
170  *
171  * @param err The error to reset.
172  *
173  * @returns AEROSPIKE_OK.
174  *
175  * @relates as_error
176  * @ingroup as_error_object
177  */
178 static inline as_status as_error_reset(as_error * err) {
179  err->code = AEROSPIKE_OK;
180  err->message[0] = '\0';
181  err->func = NULL;
182  err->file = NULL;
183  err->line = 0;
184  return err->code;
185 }
186 
187 /**
188  * Sets the error.
189  *
190  * @return The status code set for the error.
191  *
192  * @relates as_error
193  */
194 static inline as_status as_error_setall(as_error * err, as_status code, const char * message, const char * func, const char * file, uint32_t line) {
195  err->code = code;
196  strncpy(err->message, message, AS_ERROR_MESSAGE_MAX_LEN);
197  err->message[AS_ERROR_MESSAGE_MAX_LEN] = '\0';
198  err->func = func;
199  err->file = file;
200  err->line = line;
201  return err->code;
202 }
203 
204 /**
205  * Sets the error.
206  *
207  * @return The status code set for the error.
208  *
209  * @relates as_error
210  */
211 static inline as_status as_error_setallv(as_error * err, as_status code, const char * func, const char * file, uint32_t line, const char * fmt, ...) {
212  if ( fmt != NULL ) {
213  va_list ap;
214  va_start(ap, fmt);
215  vsnprintf(err->message, AS_ERROR_MESSAGE_MAX_LEN, fmt, ap);
216  err->message[AS_ERROR_MESSAGE_MAX_LEN] = '\0';
217  va_end(ap);
218  }
219  err->code = code;
220  err->func = func;
221  err->file = file;
222  err->line = line;
223  return err->code;
224 }
225 
226 /**
227  * Sets the error message
228  *
229  * @relates as_error
230  */
231 static inline as_status as_error_set(as_error * err, as_status code, const char * fmt, ...) {
232  if ( fmt != NULL ) {
233  va_list ap;
234  va_start(ap, fmt);
235  vsnprintf(err->message, AS_ERROR_MESSAGE_MAX_LEN, fmt, ap);
236  err->message[AS_ERROR_MESSAGE_MAX_LEN] = '\0';
237  va_end(ap);
238  }
239  err->code = code;
240  return err->code;
241 }
242 
243 /**
244  * Copy error from source to target.
245  *
246  * @relates as_error
247  */
248 static inline void as_error_copy(as_error * trg, as_error * src) {
249  trg->code = src->code;
250  strcpy(trg->message, src->message);
251  trg->func = src->func;
252  trg->file = src->file;
253  trg->line = src->line;
254 }
255 
256 /**
257  * Return string representation of error code. Result should not be freed.
258  *
259  * @relates as_error
260  */
261 char*
262 as_error_string(as_status status);
263 
264 #ifdef __cplusplus
265 } // end extern "C"
266 #endif