- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# svn_error.h

Go to the documentation of this file.

    00001 /**
    00002  * @copyright
    00003  * ====================================================================
    00004  *    Licensed to the Apache Software Foundation (ASF) under one
    00005  *    or more contributor license agreements.  See the NOTICE file
    00006  *    distributed with this work for additional information
    00007  *    regarding copyright ownership.  The ASF licenses this file
    00008  *    to you under the Apache License, Version 2.0 (the
    00009  *    "License"); you may not use this file except in compliance
    00010  *    with the License.  You may obtain a copy of the License at
    00011  *
    00012  *      http://www.apache.org/licenses/LICENSE-2.0
    00013  *
    00014  *    Unless required by applicable law or agreed to in writing,
    00015  *    software distributed under the License is distributed on an
    00016  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    00017  *    KIND, either express or implied.  See the License for the
    00018  *    specific language governing permissions and limitations
    00019  *    under the License.
    00020  * ====================================================================
    00021  * @endcopyright
    00022  *
    00023  * @file svn_error.h
    00024  * @brief Common exception handling for Subversion.
    00025  */
    00026
    00027 #ifndef SVN_ERROR_H
    00028 #define SVN_ERROR_H
    00029
    00030 #include <apr.h>        /* for apr_size_t */
    00031 #include <apr_errno.h>  /* APR's error system */
    00032 #include <apr_pools.h>  /* for apr_pool_t */
    00033
    00034 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00035 #define APR_WANT_STDIO
    00036 #endif
    00037 #include <apr_want.h>   /* for FILE* */
    00038
    00039 #include "svn_types.h"
    00040
    00041 #ifdef __cplusplus
    00042 extern "C" {
    00043 #endif /* __cplusplus */
    00044
    00045
    00046 /* For the Subversion developers, this #define turns on extended "stack
    00047    traces" of any errors that get thrown. See the SVN_ERR() macro.  */
    00048 #ifdef SVN_DEBUG
    00049 #define SVN_ERR__TRACING
    00050 #endif
    00051
    00052
    00053 /** the best kind of (@c svn_error_t *) ! */
    00054 #define SVN_NO_ERROR   0
    00055
    00056 /* The actual error codes are kept in a separate file; see comments
    00057    there for the reasons why. */
    00058 #include "svn_error_codes.h"
    00059
    00060 /** Put an English description of @a statcode into @a buf and return @a buf,
    00061  * NULL-terminated. @a statcode is either an svn error or apr error.
    00062  */
    00063 char *
    00064 svn_strerror(apr_status_t statcode,
    00065              char *buf,
    00066              apr_size_t bufsize);
    00067
    00068
    00069 /** If @a err has a custom error message, return that, otherwise
    00070  * store the generic error string associated with @a err->apr_err into
    00071  * @a buf (terminating with NULL) and return @a buf.
    00072  *
    00073  * @since New in 1.4.
    00074  *
    00075  * @note @a buf and @a bufsize are provided in the interface so that
    00076  * this function is thread-safe and yet does no allocation.
    00077  */
    00078 const char *svn_err_best_message(svn_error_t *err,
    00079                                  char *buf,
    00080                                  apr_size_t bufsize);
    00081
    00082
    00083
    00084 /** SVN error creation and destruction.
    00085  *
    00086  * @defgroup svn_error_error_creation_destroy Error creation and destruction
    00087  * @{
    00088  */
    00089
    00090 /** Create a nested exception structure.
    00091  *
    00092  * Input:  an APR or SVN custom error code,
    00093  *         a "child" error to wrap,
    00094  *         a specific message
    00095  *
    00096  * Returns:  a new error structure (containing the old one).
    00097  *
    00098  * @note Errors are always allocated in a subpool of the global pool,
    00099  *        since an error's lifetime is generally not related to the
    00100  *        lifetime of any convenient pool.  Errors must be freed
    00101  *        with svn_error_clear().  The specific message should be @c NULL
    00102  *        if there is nothing to add to the general message associated
    00103  *        with the error code.
    00104  *
    00105  *        If creating the "bottommost" error in a chain, pass @c NULL for
    00106  *        the child argument.
    00107  */
    00108 svn_error_t *
    00109 svn_error_create(apr_status_t apr_err,
    00110                  svn_error_t *child,
    00111                  const char *message);
    00112
    00113 /** Create an error structure with the given @a apr_err and @a child,
    00114  * with a printf-style error message produced by passing @a fmt, using
    00115  * apr_psprintf().
    00116  */
    00117 svn_error_t *
    00118 svn_error_createf(apr_status_t apr_err,
    00119                   svn_error_t *child,
    00120                   const char *fmt,
    00121                   ...)
    00122   __attribute__ ((format(printf, 3, 4)));
    00123
    00124 /** Wrap a @a status from an APR function.  If @a fmt is NULL, this is
    00125  * equivalent to svn_error_create(status,NULL,NULL).  Otherwise,
    00126  * the error message is constructed by formatting @a fmt and the
    00127  * following arguments according to apr_psprintf(), and then
    00128  * appending ": " and the error message corresponding to @a status.
    00129  * (If UTF-8 translation of the APR error message fails, the ": " and
    00130  * APR error are not appended to the error message.)
    00131  */
    00132 svn_error_t *
    00133 svn_error_wrap_apr(apr_status_t status,
    00134                    const char *fmt,
    00135                    ...)
    00136        __attribute__((format(printf, 2, 3)));
    00137
    00138 /** A quick n' easy way to create a wrapped exception with your own
    00139  * message, before throwing it up the stack.  (It uses all of the
    00140  * @a child's fields.)
    00141  */
    00142 svn_error_t *
    00143 svn_error_quick_wrap(svn_error_t *child,
    00144                      const char *new_msg);
    00145
    00146 /** Compose two errors, returning the composition as a brand new error
    00147  * and consuming the original errors.  Either or both of @a err1 and
    00148  * @a err2 may be @c SVN_NO_ERROR.  If both are not @c SVN_NO_ERROR,
    00149  * @a err2 will follow @a err1 in the chain of the returned error.
    00150  *
    00151  * Either @a err1 or @a err2 can be functions that return svn_error_t*
    00152  * but if both are functions they can be evaluated in either order as
    00153  * per the C language rules.
    00154  *
    00155  * @since New in 1.6.
    00156  */
    00157 svn_error_t *
    00158 svn_error_compose_create(svn_error_t *err1,
    00159                          svn_error_t *err2);
    00160
    00161 /** Add @a new_err to the end of @a chain's chain of errors.  The @a new_err
    00162  * chain will be copied into @a chain's pool and destroyed, so @a new_err
    00163  * itself becomes invalid after this function.
    00164  *
    00165  * Either @a chain or @a new_err can be functions that return svn_error_t*
    00166  * but if both are functions they can be evaluated in either order as
    00167  * per the C language rules.
    00168  */
    00169 void
    00170 svn_error_compose(svn_error_t *chain,
    00171                   svn_error_t *new_err);
    00172
    00173 /** Return the root cause of @a err by finding the last error in its
    00174  * chain (e.g. it or its children).  @a err may be @c SVN_NO_ERROR, in
    00175  * which case @c SVN_NO_ERROR is returned.
    00176  *
    00177  * @since New in 1.5.
    00178  */
    00179 svn_error_t *
    00180 svn_error_root_cause(svn_error_t *err);
    00181
    00182 /** Return the first error in @a err's chain that has an error code @a
    00183  * apr_err or #SVN_NO_ERROR if there is no error with that code.  The
    00184  * returned error should @em not be cleared as it shares memory with @a err.
    00185  *
    00186  * If @a err is #SVN_NO_ERROR, return #SVN_NO_ERROR.
    00187  *
    00188  * @since New in 1.7.
    00189  */
    00190 svn_error_t *
    00191 svn_error_find_cause(svn_error_t *err, apr_status_t apr_err);
    00192
    00193 /** Create a new error that is a deep copy of @a err and return it.
    00194  *
    00195  * @since New in 1.2.
    00196  */
    00197 svn_error_t *
    00198 svn_error_dup(svn_error_t *err);
    00199
    00200 /** Free the memory used by @a error, as well as all ancestors and
    00201  * descendants of @a error.
    00202  *
    00203  * Unlike other Subversion objects, errors are managed explicitly; you
    00204  * MUST clear an error if you are ignoring it, or you are leaking memory.
    00205  * For convenience, @a error may be @c NULL, in which case this function does
    00206  * nothing; thus, svn_error_clear(svn_foo(...)) works as an idiom to
    00207  * ignore errors.
    00208  */
    00209 void
    00210 svn_error_clear(svn_error_t *error);
    00211
    00212
    00213 #if defined(SVN_DEBUG)
    00214 /** Set the error location for debug mode. */
    00215 void
    00216 svn_error__locate(const char *file,
    00217                   long line);
    00218
    00219 /* Wrapper macros to collect file and line information */
    00220 #define svn_error_create \
    00221   (svn_error__locate(__FILE__,__LINE__), (svn_error_create))
    00222 #define svn_error_createf \
    00223   (svn_error__locate(__FILE__,__LINE__), (svn_error_createf))
    00224 #define svn_error_wrap_apr \
    00225   (svn_error__locate(__FILE__,__LINE__), (svn_error_wrap_apr))
    00226 #define svn_error_quick_wrap \
    00227   (svn_error__locate(__FILE__,__LINE__), (svn_error_quick_wrap))
    00228 #endif
    00229
    00230
    00231 /**
    00232  * Very basic default error handler: print out error stack @a error to the
    00233  * stdio stream @a stream, with each error prefixed by @a prefix; quit and
    00234  * clear @a error iff the @a fatal flag is set.  Allocations are performed
    00235  * in the @a error's pool.
    00236  *
    00237  * If you're not sure what prefix to pass, just pass "svn: ".  That's
    00238  * what code that used to call svn_handle_error() and now calls
    00239  * svn_handle_error2() does.
    00240  *
    00241  * @since New in 1.2.
    00242  */
    00243 void
    00244 svn_handle_error2(svn_error_t *error,
    00245                   FILE *stream,
    00246                   svn_boolean_t fatal,
    00247                   const char *prefix);
    00248
    00249 /** Like svn_handle_error2() but with @c prefix set to "svn: "
    00250  *
    00251  * @deprecated Provided for backward compatibility with the 1.1 API.
    00252  */
    00253 SVN_DEPRECATED
    00254 void
    00255 svn_handle_error(svn_error_t *error,
    00256                  FILE *stream,
    00257                  svn_boolean_t fatal);
    00258
    00259 /**
    00260  * Very basic default warning handler: print out the error @a error to the
    00261  * stdio stream @a stream, prefixed by @a prefix.  Allocations are
    00262  * performed in the error's pool.
    00263  *
    00264  * @a error may not be @c NULL.
    00265  *
    00266  * @since New in 1.2.
    00267  */
    00268 void
    00269 svn_handle_warning2(FILE *stream,
    00270                     svn_error_t *error,
    00271                     const char *prefix);
    00272
    00273 /** Like svn_handle_warning2() but with @c prefix set to "svn: "
    00274  *
    00275  * @deprecated Provided for backward compatibility with the 1.1 API.
    00276  */
    00277 SVN_DEPRECATED
    00278 void
    00279 svn_handle_warning(FILE *stream,
    00280                    svn_error_t *error);
    00281
    00282
    00283 /** A statement macro for checking error values.
    00284  *
    00285  * Evaluate @a expr.  If it yields an error, return that error from the
    00286  * current function.  Otherwise, continue.
    00287  *
    00288  * The <tt>do { ... } while (0)</tt> wrapper has no semantic effect,
    00289  * but it makes this macro syntactically equivalent to the expression
    00290  * statement it resembles.  Without it, statements like
    00291  *
    00292  * @code
    00293  *   if (a)
    00294  *     SVN_ERR(some operation);
    00295  *   else
    00296  *     foo;
    00297  * @endcode
    00298  *
    00299  * would not mean what they appear to.
    00300  */
    00301 #define SVN_ERR(expr)                           \
    00302   do {                                          \
    00303     svn_error_t *svn_err__temp = (expr);        \
    00304     if (svn_err__temp)                          \
    00305       return svn_error_trace(svn_err__temp);    \
    00306   } while (0)
    00307
    00308 /**
    00309  * A macro for wrapping an error in a source-location trace message.
    00310  *
    00311  * This macro can be used when directly returning an already created
    00312  * error (when not using SVN_ERR, svn_error_create(), etc.) to ensure
    00313  * that the call stack is recorded correctly.
    00314  *
    00315  * @since New in 1.7.
    00316  */
    00317 #ifdef SVN_ERR__TRACING
    00318 #define SVN_ERR__TRACED "traced call"
    00319
    00320 #define svn_error_trace(expr)  svn_error_quick_wrap((expr), SVN_ERR__TRACED)
    00321 #else
    00322 #define svn_error_trace(expr)  (expr)
    00323 #endif
    00324
    00325 /**
    00326  * Returns an error chain that is based on @a err's error chain but
    00327  * does not include any error tracing placeholders.  @a err is not
    00328  * modified, except for any allocations using its pool.
    00329  *
    00330  * The returned error chain is allocated from @a err's pool and shares
    00331  * its message and source filename character arrays.  The returned
    00332  * error chain should *not* be cleared because it is not a fully
    00333  * fledged error chain, only clearing @a err should be done to clear
    00334  * the returned error chain.  If @a err is cleared, then the returned
    00335  * error chain is unusable.
    00336  *
    00337  * @a err can be #SVN_NO_ERROR.  If @a err is not #SVN_NO_ERROR, then
    00338  * the last link in the error chain must be a non-tracing error, i.e,
    00339  * a real error.
    00340  *
    00341  * @since New in 1.7.
    00342  */
    00343 svn_error_t *svn_error_purge_tracing(svn_error_t *err);
    00344
    00345
    00346 /** A statement macro, very similar to @c SVN_ERR.
    00347  *
    00348  * This macro will wrap the error with the specified text before
    00349  * returning the error.
    00350  */
    00351 #define SVN_ERR_W(expr, wrap_msg)                           \
    00352   do {                                                      \
    00353     svn_error_t *svn_err__temp = (expr);                    \
    00354     if (svn_err__temp)                                      \
    00355       return svn_error_quick_wrap(svn_err__temp, wrap_msg); \
    00356   } while (0)
    00357
    00358
    00359 /** A statement macro, similar to @c SVN_ERR, but returns an integer.
    00360  *
    00361  * Evaluate @a expr. If it yields an error, handle that error and
    00362  * return @c EXIT_FAILURE.
    00363  */
    00364 #define SVN_INT_ERR(expr)                                        \
    00365   do {                                                           \
    00366     svn_error_t *svn_err__temp = (expr);                         \
    00367     if (svn_err__temp) {                                         \
    00368       svn_handle_error2(svn_err__temp, stderr, FALSE, "svn: ");  \
    00369       svn_error_clear(svn_err__temp);                            \
    00370       return EXIT_FAILURE; }                                     \
    00371   } while (0)
    00372
    00373 /** @} */
    00374
    00375
    00376 /** Error groups
    00377  *
    00378  * @defgroup svn_error_error_groups Error groups
    00379  * @{
    00380  */
    00381
    00382 /**
    00383  * Return TRUE if @a err is an error specifically related to locking a
    00384  * path in the repository, FALSE otherwise.
    00385  *
    00386  * SVN_ERR_FS_OUT_OF_DATE and SVN_ERR_FS_NOT_FOUND are in here because it's a
    00387  * non-fatal error that can be thrown when attempting to lock an item.
    00388  *
    00389  * @since New in 1.2.
    00390  */
    00391 #define SVN_ERR_IS_LOCK_ERROR(err)                          \
    00392   (err->apr_err == SVN_ERR_FS_PATH_ALREADY_LOCKED ||        \
    00393    err->apr_err == SVN_ERR_FS_NOT_FOUND           ||        \
    00394    err->apr_err == SVN_ERR_FS_OUT_OF_DATE         ||        \
    00395    err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN)
    00396
    00397 /**
    00398  * Return TRUE if @a err is an error specifically related to unlocking
    00399  * a path in the repository, FALSE otherwise.
    00400  *
    00401  * @since New in 1.2.
    00402  */
    00403 #define SVN_ERR_IS_UNLOCK_ERROR(err)                        \
    00404   (err->apr_err == SVN_ERR_FS_PATH_NOT_LOCKED ||            \
    00405    err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN ||             \
    00406    err->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH ||        \
    00407    err->apr_err == SVN_ERR_FS_NO_SUCH_LOCK ||               \
    00408    err->apr_err == SVN_ERR_RA_NOT_LOCKED ||                 \
    00409    err->apr_err == SVN_ERR_FS_LOCK_EXPIRED)
    00410
    00411 /** Evaluates to @c TRUE iff @a apr_err (of type #apr_status_t) is in the given
    00412  * @a category, which should be one of the @c SVN_ERR_*_CATEGORY_START
    00413  * constants.
    00414  *
    00415  * @since New in 1.7.
    00416  */
    00417 #define SVN_ERROR_IN_CATEGORY(apr_err, category)            \
    00418     ((category) == ((apr_err) / SVN_ERR_CATEGORY_SIZE) * SVN_ERR_CATEGORY_SIZE)
    00419
    00420
    00421 /** @} */
    00422
    00423
    00424 /** Internal malfunctions and assertions
    00425  *
    00426  * @defgroup svn_error_malfunction_assertion Malfunctions and assertions
    00427  * @{
    00428  */
    00429
    00430 /** Report that an internal malfunction has occurred, and possibly terminate
    00431  * the program.
    00432  *
    00433  * Act as determined by the current "malfunction handler" which may have
    00434  * been specified by a call to svn_error_set_malfunction_handler() or else
    00435  * is the default handler as specified in that function's documentation. If
    00436  * the malfunction handler returns, then cause the function using this macro
    00437  * to return the error object that it generated.
    00438  *
    00439  * @note The intended use of this macro is where execution reaches a point
    00440  * that cannot possibly be reached unless there is a bug in the program.
    00441  *
    00442  * @since New in 1.6.
    00443  */
    00444 #define SVN_ERR_MALFUNCTION()                                      \
    00445   do {                                                             \
    00446     return svn_error_trace(svn_error__malfunction(                 \
    00447                                  TRUE, __FILE__, __LINE__, NULL)); \
    00448   } while (0)
    00449
    00450 /** Similar to SVN_ERR_MALFUNCTION(), but without the option of returning
    00451  * an error to the calling function.
    00452  *
    00453  * If possible you should use SVN_ERR_MALFUNCTION() instead.
    00454  *
    00455  * @since New in 1.6.
    00456  */
    00457 #define SVN_ERR_MALFUNCTION_NO_RETURN()                      \
    00458   do {                                                       \
    00459     svn_error__malfunction(FALSE, __FILE__, __LINE__, NULL); \
    00460     abort();                                                 \
    00461   } while (1)
    00462
    00463 /** Check that a condition is true: if not, report an error and possibly
    00464  * terminate the program.
    00465  *
    00466  * If the Boolean expression @a expr is true, do nothing. Otherwise,
    00467  * act as determined by the current "malfunction handler" which may have
    00468  * been specified by a call to svn_error_set_malfunction_handler() or else
    00469  * is the default handler as specified in that function's documentation. If
    00470  * the malfunction handler returns, then cause the function using this macro
    00471  * to return the error object that it generated.
    00472  *
    00473  * @note The intended use of this macro is to check a condition that cannot
    00474  * possibly be false unless there is a bug in the program.
    00475  *
    00476  * @note The condition to be checked should not be computationally expensive
    00477  * if it is reached often, as, unlike traditional "assert" statements, the
    00478  * evaluation of this expression is not compiled out in release-mode builds.
    00479  *
    00480  * @since New in 1.6.
    00481  */
    00482 #define SVN_ERR_ASSERT(expr)                                            \
    00483   do {                                                                  \
    00484     if (!(expr))                                                        \
    00485       SVN_ERR(svn_error__malfunction(TRUE, __FILE__, __LINE__, #expr)); \
    00486   } while (0)
    00487
    00488 /** Similar to SVN_ERR_ASSERT(), but without the option of returning
    00489  * an error to the calling function.
    00490  *
    00491  * If possible you should use SVN_ERR_ASSERT() instead.
    00492  *
    00493  * @since New in 1.6.
    00494  */
    00495 #define SVN_ERR_ASSERT_NO_RETURN(expr)                          \
    00496   do {                                                          \
    00497     if (!(expr)) {                                              \
    00498       svn_error__malfunction(FALSE, __FILE__, __LINE__, #expr); \
    00499       abort();                                                  \
    00500     }                                                           \
    00501   } while (0)
    00502
    00503 /** Report a "Not implemented" malfunction.  Internal use only. */
    00504 #define SVN__NOT_IMPLEMENTED() \
    00505   return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.")
    00506
    00507 /** A helper function for the macros that report malfunctions. Handle a
    00508  * malfunction by calling the current "malfunction handler" which may have
    00509  * been specified by a call to svn_error_set_malfunction_handler() or else
    00510  * is the default handler as specified in that function's documentation.
    00511  *
    00512  * Pass all of the parameters to the handler. The error occurred in the
    00513  * source file @a file at line @a line, and was an assertion failure of the
    00514  * expression @a expr, or, if @a expr is null, an unconditional error.
    00515  *
    00516  * If @a can_return is true, the handler can return an error object
    00517  * that is returned by the caller. If @a can_return is false the
    00518  * method should never return. (The caller will call abort())
    00519  *
    00520  * @since New in 1.6.
    00521  */
    00522 svn_error_t *
    00523 svn_error__malfunction(svn_boolean_t can_return,
    00524                        const char *file,
    00525                        int line,
    00526                        const char *expr);
    00527
    00528 /** A type of function that handles an assertion failure or other internal
    00529  * malfunction detected within the Subversion libraries.
    00530  *
    00531  * The error occurred in the source file @a file at line @a line, and was an
    00532  * assertion failure of the expression @a expr, or, if @a expr is null, an
    00533  * unconditional error.
    00534  *
    00535  * If @a can_return is false a function of this type must never return.
    00536  *
    00537  * If @a can_return is true a function of this type must do one of:
    00538  *   - Return an error object describing the error, using an error code in
    00539  *     the category SVN_ERR_MALFUNC_CATEGORY_START.
    00540  *   - Never return.
    00541  *
    00542  * The function may alter its behaviour according to compile-time
    00543  * and run-time and even interactive conditions.
    00544  *
    00545  * @see SVN_ERROR_IN_CATEGORY()
    00546  *
    00547  * @since New in 1.6.
    00548  */
    00549 typedef svn_error_t *(*svn_error_malfunction_handler_t)
    00550   (svn_boolean_t can_return, const char *file, int line, const char *expr);
    00551
    00552 /** Cause subsequent malfunctions to be handled by @a func.
    00553  * Return the handler that was previously in effect.
    00554  *
    00555  * @a func may not be null.
    00556  *
    00557  * @note The default handler is svn_error_abort_on_malfunction().
    00558  *
    00559  * @note This function must be called in a single-threaded context.
    00560  *
    00561  * @since New in 1.6.
    00562  */
    00563 svn_error_malfunction_handler_t
    00564 svn_error_set_malfunction_handler(svn_error_malfunction_handler_t func);
    00565
    00566 /** Handle a malfunction by returning an error object that describes it.
    00567  *
    00568  * When @a can_return is false, abort()
    00569  *
    00570  * This function implements @c svn_error_malfunction_handler_t.
    00571  *
    00572  * @since New in 1.6.
    00573  */
    00574 svn_error_t *
    00575 svn_error_raise_on_malfunction(svn_boolean_t can_return,
    00576                                const char *file,
    00577                                int line,
    00578                                const char *expr);
    00579
    00580 /** Handle a malfunction by printing a message to stderr and aborting.
    00581  *
    00582  * This function implements @c svn_error_malfunction_handler_t.
    00583  *
    00584  * @since New in 1.6.
    00585  */
    00586 svn_error_t *
    00587 svn_error_abort_on_malfunction(svn_boolean_t can_return,
    00588                                const char *file,
    00589                                int line,
    00590                                const char *expr);
    00591
    00592 /** @} */
    00593
    00594
    00595 #ifdef __cplusplus
    00596 }
    00597 #endif /* __cplusplus */
    00598
    00599 #endif /* SVN_ERROR_H */

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines