Exception handling

Exception handling — A way for Cogl to throw exceptions

Synopsis

                    CoglError;
CoglBool            cogl_error_matches                  (CoglError *error,
                                                         uint32_t domain,
                                                         int code);
void                cogl_error_free                     (CoglError *error);
CoglError *         cogl_error_copy                     (CoglError *error);
#define             COGL_GLIB_ERROR                     (COGL_ERROR)

Description

As a general rule Cogl shields non-recoverable errors from developers, such as most heap allocation failures (unless for exceptionally large resources which we might reasonably expect to fail) and this reduces the burden on developers.

There are some Cogl apis though that can fail for exceptional reasons that can also potentially be recovered from at runtime and for these apis we use a standard convention for reporting runtime recoverable errors.

As an example if we look at the cogl_context_new() api which takes an error argument:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19










CoglContext *
  cogl_context_new (CoglDisplay *display, CoglError **error);

A caller interested in catching any runtime error when creating a new CoglContext would pass the address of a CoglError pointer that has first been initialized to NULL as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22










CoglError *error = NULL;
  CoglContext *context;

  context = cogl_context_new (NULL, &error);

The return status should usually be enough to determine if there was an error set (in this example we can check if context == NULL) but if it's not possible to tell from the function's return status you can instead look directly at the error pointer which you initialized to NULL. In this example we now check the error, report any error to the user, free the error and then simply abort without attempting to recover.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27










if (context == NULL)
    {
      fprintf (stderr, "Failed to create a Cogl context: %s\n",
               error->message);
      cogl_error_free (error);
      abort ();
    }

All Cogl APIs that accept an error argument can also be passed a NULL pointer. In this case if an exceptional error condition is hit then Cogl will simply log the error message and abort the application. This can be compared to language execeptions where the developer has not attempted to catch the exception. This means the above example is essentially redundant because it's what Cogl would have done automatically and so, similarly, if your application has no way to recover from a particular error you might just as well pass a NULL CoglError pointer to save a bit of typing.

Note

If you are used to using the GLib API you will probably recognize that CoglError is just like a GError. In fact if Cogl has been built with --enable-glib then it is safe to cast a CoglError to a GError.

Note

An important detail to be aware of if you are used to using GLib's GError API is that Cogl deviates from the GLib GError conventions in one noteable way which is that a NULL error pointer does not mean you want to ignore the details of an error, it means you are not trying to catch any exceptional errors the function might throw which will result in the program aborting with a log message if an error is thrown.

Details

CoglError

typedef struct {
  uint32_t domain;
  int code;
  char *message;
} CoglError;

uint32_t domain;

A high-level domain identifier for the error

int code;

A specific error code within a specified domain

char *message;

A human readable error message

cogl_error_matches ()

CoglBool            cogl_error_matches                  (CoglError *error,
                                                         uint32_t domain,
                                                         int code);

Returns TRUE if error matches domain and code, FALSE otherwise. In particular, when error is NULL, FALSE will be returned.

error :

A CoglError thrown by the Cogl api or NULL

domain :

The error domain

code :

The error code

Returns :

whether the error corresponds to the given domain and code.

cogl_error_free ()

void                cogl_error_free                     (CoglError *error);

Frees a CoglError and associated resources.

error :

A CoglError thrown by the Cogl api

cogl_error_copy ()

CoglError *         cogl_error_copy                     (CoglError *error);

Makes a copy of error which can later be freed using cogl_error_free().

error :

A CoglError thrown by the Cogl api

Returns :

A newly allocated CoglError initialized to match the contents of error.

COGL_GLIB_ERROR()

#define COGL_GLIB_ERROR(COGL_ERROR) ((CoglError *)COGL_ERROR)

Simply casts a CoglError to a CoglError

If Cogl is built with GLib support then it can safely be assumed that a CoglError is a GError and can be used directly with the GError api.

COGL_ERROR :

A CoglError thrown by the Cogl api or NULL