Commit d6c60169 by Russell Belfer

Add giterr_detach API to get and clear error

There are a number of cases where it is convenient to be able to
fetch and "claim" the current error string, clearing the error.
This is helpful when you need to call some code that may alter
the error and you want to restore it later on and/or report it via
some other mechanism.
parent 0e1115d2
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define INCLUDE_git_errors_h__ #define INCLUDE_git_errors_h__
#include "common.h" #include "common.h"
#include "buffer.h"
/** /**
* @file git2/errors.h * @file git2/errors.h
...@@ -45,6 +46,7 @@ typedef struct { ...@@ -45,6 +46,7 @@ typedef struct {
/** Error classes */ /** Error classes */
typedef enum { typedef enum {
GITERR_NONE = 0,
GITERR_NOMEMORY, GITERR_NOMEMORY,
GITERR_OS, GITERR_OS,
GITERR_INVALID, GITERR_INVALID,
...@@ -85,6 +87,21 @@ GIT_EXTERN(const git_error *) giterr_last(void); ...@@ -85,6 +87,21 @@ GIT_EXTERN(const git_error *) giterr_last(void);
GIT_EXTERN(void) giterr_clear(void); GIT_EXTERN(void) giterr_clear(void);
/** /**
* Get the last error data and clear it.
*
* This copies the last error message into the given `git_buf` and returns
* the associated `git_error_t`, leaving the error cleared as if
* `giterr_clear` had been called. You must call `git_buf_free` on the
* message to release the memory.
*
* Note: it is possible that this will return `GITERR_NONE` and set the
* buffer to NULL, so be prepared for that condition. Also, if the last
* error was an out-of-memory error, this will return `GITERR_NOMEMORY`
* but also leave the buffer set to NULL (to avoid allocation).
*/
GIT_EXTERN(git_error_t) giterr_detach(git_buf *message);
/**
* Set the error message string for this thread. * Set the error message string for this thread.
* *
* This function is public so that custom ODB backends and the like can * This function is public so that custom ODB backends and the like can
......
...@@ -112,6 +112,29 @@ void giterr_clear(void) ...@@ -112,6 +112,29 @@ void giterr_clear(void)
#endif #endif
} }
git_error_t giterr_detach(git_buf *message)
{
git_error_t rval;
git_error *error = GIT_GLOBAL->last_error;
assert(message);
git_buf_free(message);
if (!error)
return GITERR_NONE;
rval = error->klass;
if (error != &g_git_oom_error)
git_buf_attach(message, error->message, 0);
error->message = NULL;
giterr_clear();
return rval;
}
const git_error *giterr_last(void) const git_error *giterr_last(void)
{ {
return GIT_GLOBAL->last_error; return GIT_GLOBAL->last_error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment