adapting new-error-handling in pygit2

New error handling in libgit2 is now done the posix way. One error code for each expected failure,
and a generic error code for all critical ones. The last error can be accessed by giterr_last().
It returns a pointer to the global error struct.

For more information see docs/error-handling.md in libgit2.
This commit is contained in:
Nico von Geyso 2012-05-16 10:58:52 +02:00
parent 2bbf62f50a
commit 8dd0c18c62

@ -165,46 +165,62 @@ static PyTypeObject SignatureType;
static PyObject *GitError;
static PyObject *
Error_type(int err)
Error_type(int type)
{
switch (err) {
// Expected
switch (type) {
/** Input does not exist in the scope searched. */
case GIT_ENOTFOUND:
return PyExc_KeyError;
case GIT_EOSERR:
return PyExc_OSError;
case GIT_ENOTOID:
/** A reference with this name already exists */
case GIT_EEXISTS:
return PyExc_ValueError;
case GIT_ENOMEM:
return PyExc_MemoryError;
case GIT_EREVWALKOVER:
/** The given short oid is ambiguous */
case GIT_EAMBIGUOUS:
return PyExc_ValueError;
/** The buffer is too short to satisfy the request */
case GIT_EBUFS:
return PyExc_ValueError;
/** Skip and passthrough the given ODB backend */
case GIT_PASSTHROUGH:
return GitError;
/** No entries left in ref walker */
case GIT_REVWALKOVER:
return PyExc_StopIteration;
}
// Critical
const git_error* error = giterr_last();
switch (error->klass) {
case GITERR_NOMEMORY:
return PyExc_MemoryError;
case GITERR_OS:
return PyExc_OSError;
case GITERR_INVALID:
return PyExc_ValueError;
default:
return GitError;
}
}
/*
* Python doesn't like it when the error string is NULL. Not giving
* back an error string could be a bug in the library
*/
static const char *
git_last_error(void)
{
const char *ret;
ret = git_lasterror();
return ret != NULL ? ret : "(No error information given)";
}
static PyObject *
Error_set(int err)
{
assert(err < 0);
if (err == GIT_EOSERR)
return PyErr_SetFromErrno(GitError);
if(err != GIT_ERROR) { //expected failure
PyErr_SetNone(Error_type(err));
} else { //critical failure
const git_error* error = giterr_last();
PyErr_SetString(Error_type(err), error->message);
}
PyErr_SetString(Error_type(err), git_last_error());
return NULL;
}
@ -217,7 +233,8 @@ Error_set_str(int err, const char *str)
return NULL;
}
return PyErr_Format(Error_type(err), "%s: %s", str, git_last_error());
const git_error* error = giterr_last();
return PyErr_Format(Error_type(err), "%s: %s", str, error->message);
}
static PyObject *
@ -838,7 +855,7 @@ Repository_listall_references(Repository *self, PyObject *args)
return NULL;
/* 2- Get the C result */
err = git_reference_listall(&c_result, self->repo, list_flags);
err = git_reference_list(&c_result, self->repo, list_flags);
if (err < 0)
return Error_set(err);
@ -957,7 +974,7 @@ read_status_cb(const char *path, unsigned int status_flags, void *payload)
flags = PyInt_FromLong((long) status_flags);
PyDict_SetItemString(payload, path, flags);
return GIT_SUCCESS;
return GIT_OK;
}
static PyObject *
@ -1009,7 +1026,8 @@ Repository_TreeBuilder(Repository *self, PyObject *args)
if (PyObject_TypeCheck(py_src, &TreeType)) {
Tree *py_tree = (Tree *)py_src;
if (py_tree->repo->repo != self->repo) {
return Error_set(GIT_EINVALIDARGS);
//return Error_set(GIT_EINVALIDARGS);
return Error_set(GIT_ERROR);
}
tree = py_tree->tree;
} else {
@ -2118,7 +2136,7 @@ Index_read(Index *self)
int err;
err = git_index_read(self->index);
if (err < GIT_SUCCESS)
if (err < GIT_OK)
return Error_set(err);
Py_RETURN_NONE;
@ -2130,7 +2148,7 @@ Index_write(Index *self)
int err;
err = git_index_write(self->index);
if (err < GIT_SUCCESS)
if (err < GIT_OK)
return Error_set(err);
Py_RETURN_NONE;
@ -2868,7 +2886,7 @@ Reference_get_hex(Reference *self)
static PyObject *
Reference_get_type(Reference *self)
{
git_rtype c_type;
git_ref_t c_type;
CHECK_REFERENCE(self);
c_type = git_reference_type(self->reference);