Re: [Evolution-hackers] Heads Up: More Camel API breakage in 2.31



On Tue, 2010-07-13 at 18:50 +0200, Christian Hilberg wrote:
> Is there a sensible way how we could deal with CamelException in our 
> evolution-kolab plugin, which will be developed against 2.30? This is, can 
> CamelException be wrapped in a way which will ease up the transition to 
> GError, once our plugin will be ported to 2.31?

There are a few habits to follow with CamelException which will ease the
transition to GError:


  - A CamelException instance allows you to set multiple errors on it
    such that new errors silently overwrite old errors.  This is evil,
    and I spent a lot of time cleaning up old code that relied on it.

    Check for an error and react accordingly after -every- step that
    could fail.  Don't do a bunch of steps and then check for error. 
    This is good programming practice anyway.


  - By convention, passing a GError is always optional.  Not so with
    CamelException.  This gets you into trouble when you have to examine
    the CamelException for specific error codes: you can count on the
    caller passing you a CamelException, you CAN'T count on the caller
    passing you a GError.

    So while it may be tempting to use the caller's CamelException
    directly, do this instead: pass a locally allocated CamelException
    to the failable function, examine -that- for specific error codes,
    and if necessary propagate it to the CamelException that was passed
    in by the caller.  That's the pattern you would use with GError.

    So for example:

    gboolean
    do_something (CamelFolder *folder,
                  CamelException *ex)
    {
            CamelException local_ex;

            camel_exception_init (&local_ex);

            do_something_that_can_fail (folder, &local_ex);

            /* With CamelException, you could safely use and examine
             * "ex" directly, since "ex" should never be NULL. */

            if (camel_exception_get_id (&local_ex) == ERROR_CODE)
                    ... do some damage control ...

            /* Propagate the error to the caller's CamelException. */
            if (camel_exception_is_set (&local_ex)) {
                    camel_exception_xfer (ex, &local_ex);
                    return FALSE;
            }

            return TRUE;
    }

    Equivalent function with GError:

    gboolean
    do_something (CamelFolder *folder,
                  GError **error)
    {
            GError *local_error = NULL;

            do_something_that_can_fail (folder, &local_error);

            /* With GError, "error" might be NULL.  So we need our
             * own local GError that we know is safe to examine. */

            if (g_error_matches (local_error, ERROR_DOMAIN, ERROR_CODE))
                    ... do some damage control ...

            /* Propagate the error to the caller's GError. */
            if (local_error != NULL) {
                    g_propagate_error (error, local_error);
                    return FALSE;
            }

            return TRUE;
    }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]