Re: GError



As a programmer, I would prefer the more-complicated solution Tim
outlines here, rather than the simpler GError proposal that seems to be
carrying the day.

In fact, I would go farther, and just make GError a type in the object
system, with the module and blurb fields.  The implementation of GError
can cover the most common case, of just the module, and error code, and
a blurb, and when you need to pass additional information, you can just
derive from GError.

Walt

P.S. I think "blurb" is a catchy name for the error message field.
Tim Janik wrote:
>
> at this point i wonder whether you at all considered using the type system
> here, extending a bit on havoc's recent approach (imho somewhat bloated, but
> spinnig this for the pure fun), provide convenient registration functions:
> 
> the Foo module wants to throw OutOfResource (OFR) errors which supply
> additional information as to what resource and when this happened:
> 
> typedef struct
> {
>   GError    base;
>   gchar    *resource;
>   GTimeVal  stamp;
> } FooErrorOFR;
> 
> /* register this error type once */
> GType foo_ofr = g_error_register_new ("FooOutOfResource",
>                                       sizeof (FooErrorOFR),
>                                       foo_ofr_error_copy,
>                                       foo_ofr_error_free);
> 
> GError*
> foo_error_ofr (gint code, gchar *resource, gchar *format, ...)
> {
>   FoorErrorOFR *error;
>   va_list var_args;
> 
>   va_start (var_args, format);
>   error = g_error_new_valist (foo_ofr, code, va_list);
>   va_end (var_args);
> 
>   error->resource = g_strdup (resource);
>   g_get_current_time (&error->stamp);
> 
>   return G_ERROR (error);
> }
> 
> error throwing code example:
> {
>   gint fd = open ("/tmp/myspool", O_CREAT);
> 
>   if (fd < 0 && (errno == EMFILE || errno == ENFILE))
>     return foo_error_ofr (errno, "filedescriptors",
>                           "failed to open %s", "/tmp/myspool");
> 
> error handling code:
>   if (g_error_is_a (G_ERROR (error), foo_ofr))
>     g_print ("Stamp-%u: %s: No %s available\n",
>              error->stamp, error->base->blurb, error->resource);
> 
> that may seem a bit bloated, but to be practical, all that's new here is the
> one call to g_error_register_new(). the typedef struct {} FooErrorOFR; has to
> be supplied if the gpointer data; or owen's GError err; embedding approach is
> used, and foo_ofr_error_copy() as well as foo_ofr_error_free() already came
> with havoc's latest proposal (and you'd need a foo_error_ofr() constructor for
> those as well).
> the advantage here is that foo_ofr_error_copy() and foo_ofr_error_free() don't
> need to be supplied with every error creation call (thus doing a better job at
> encapsulation, allowing multiple error constructors that behave differently),
> and the error itself can be passed around in GValue structures since its
> registered with the type system.
> 
> note that use of g_error_register_new() isn't mandatory, for sane programmers
> that just need a descriptive string and an error code, the plain g_error()
> API is fully sufficient.




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