After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 618193 - Can't handle GError * as a callback argument
Can't handle GError * as a callback argument
Status: RESOLVED OBSOLETE
Product: gjs
Classification: Bindings
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gjs-maint
gjs-maint
: 617495 (view as bug list)
Depends on:
Blocks: 654475
 
 
Reported: 2010-05-09 19:34 UTC by Morten Mjelva
Modified: 2012-08-26 11:39 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
source (9.33 KB, text/x-csrc)
2010-05-09 19:35 UTC, Morten Mjelva
  Details
header (3.04 KB, text/x-chdr)
2010-05-09 19:35 UTC, Morten Mjelva
  Details
Add tests for callbacks with GErrors (4.18 KB, patch)
2011-07-12 17:06 UTC, Giovanni Campagna
none Details | Review
Support callbacks that accept GErrors (2.43 KB, patch)
2011-07-12 17:09 UTC, Giovanni Campagna
none Details | Review

Description Morten Mjelva 2010-05-09 19:34:32 UTC
I've included the source and header files for the function i'm calling (get_position_async).

$ GJS_DEBUG_OUTPUT=stderr ~/sandbox/bin/gjs current_position_async.
      JS LOG: Command line: /home/mortenmj/sandbox/bin/gjs current_position_async.js
      JS CTX: Creating new context to eval console script
      JS CTX: Enabling JIT
      JS CTX: Changing JavaScript version to 1.8 from default
      JS CTX: Creating load context for runtime 0x88f5868
      JS CTX: Enabling JIT
      JS CTX: Changing JavaScript version to 1.8 from default
   JS IMPORT: Initialized class GjsFileImporter prototype 0x891e720
   JS IMPORT: Defining parent 0x891e3a0 of 0x891e740 'imports' is mod 0
   JS IMPORT: Defined importer 'imports' 0x891e740 in 0x891e3a0
   JS IMPORT: JS import 'dbus' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'dbus' not found in /usr/local/share/gjs-1.0
   JS IMPORT: Importing '/usr/share/gjs-1.0/dbus.js'
   JS IMPORT: Defining parent 0x891e740 of 0x891e7e0 'dbus' is mod 1
   JS IMPORT: JS import 'lang' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'lang' not found in /usr/local/share/gjs-1.0
   JS IMPORT: Importing '/usr/share/gjs-1.0/lang.js'
   JS IMPORT: Defining parent 0x891e740 of 0x891eca0 'lang' is mod 1
   JS IMPORT: JS import 'langNative' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'langNative' not found in /usr/local/share/gjs-1.0
   JS IMPORT: JS import 'langNative' not found in /usr/share/gjs-1.0
   JS IMPORT: Importing '/home/mortenmj/sandbox/lib/gjs-1.0/langNative.so'
   JS IMPORT: Defining parent 0x891e740 of 0x891ed60 'langNative' is mod 1
   JS NATIVE: Registered native JS module 'langNative'
   JS NATIVE: Defining native module 'langNative'
   JS IMPORT: successfully imported module 'langNative'
   JS IMPORT: successfully imported module 'lang'
   JS IMPORT: JS import 'dbusNative' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'dbusNative' not found in /usr/local/share/gjs-1.0
   JS IMPORT: JS import 'dbusNative' not found in /usr/share/gjs-1.0
   JS IMPORT: Importing '/home/mortenmj/sandbox/lib/gjs-1.0/dbusNative.so'
   JS IMPORT: Defining parent 0x891e740 of 0x891eda0 'dbusNative' is mod 1
   JS NATIVE: Registered native JS module 'dbusNative'
   JS NATIVE: Defining native module 'dbusNative'
     JS DBUS: Initialized class DBusExports prototype 0x891ee00
   JS IMPORT: successfully imported module 'dbusNative'
   JS IMPORT: successfully imported module 'dbus'
   JS IMPORT: JS import 'gi' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'gi' not found in /usr/local/share/gjs-1.0
   JS IMPORT: JS import 'gi' not found in /usr/share/gjs-1.0
   JS IMPORT: Importing '/home/mortenmj/sandbox/lib/gjs-1.0/gi.so'
   JS IMPORT: Defining parent 0x891e740 of 0x89622c0 'gi' is mod 1
   JS NATIVE: Registered native JS module 'gi'
   JS NATIVE: Defining native module 'gi'
   JS G REPO: Initialized class GIRepository prototype 0x89622e0
     JS G NS: Initialized class GIRepositoryNamespace prototype 0x8962340
     JS G NS: Defined namespace 'GLib' 0x8962360 in GIRepository 0x8962300
   JS IMPORT: successfully imported module 'gi'
     JS G NS: Defined namespace 'Geoclue' 0x8962380 in GIRepository 0x8962300
   JS IMPORT: JS import 'mainloop' not found in /usr/share/gnome/gjs-1.0
   JS IMPORT: JS import 'mainloop' not found in /usr/local/share/gjs-1.0
   JS IMPORT: JS import 'mainloop' not found in /usr/share/gjs-1.0
   JS IMPORT: Importing '/home/mortenmj/sandbox/lib/gjs-1.0/mainloop.so'
   JS IMPORT: Defining parent 0x891e740 of 0x89623a0 'mainloop' is mod 1
   JS NATIVE: Registered native JS module 'mainloop'
   JS NATIVE: Defining native module 'mainloop'
   JS IMPORT: successfully imported module 'mainloop'
     JS G NS: Found info type OBJECT for 'Master' in namespace 'Geoclue'
     JS G NS: Found info type OBJECT for 'Master' in namespace 'Geoclue'
     JS G NS: Defined namespace 'GObject' 0x89623c0 in GIRepository 0x8962300
     JS G NS: Found info type OBJECT for 'Object' in namespace 'GObject'
   JS G REPO: Initializing dynamic class Object 0x894d410
    JS G OBJ: Defined class Object prototype 0x89623e0 class 0x894d410 in object 0x89623c0
   JS G REPO: Initializing dynamic class Master 0x894d460
    JS G OBJ: Defined class Master prototype 0x8962400 class 0x894d460 in object 0x8962380
   JS G FUNC: Initialized class GIRepositoryFunction prototype 0x8962420
   JS KP ALV: Initializing keep-alive class in context 0x892f7c0 global 0x891e3a0
   JS KP ALV: Initialized class __private_GjsKeepAlive prototype 0x8962480
   JS KP ALV: Creating new keep-alive object for context 0x892f7c0 global 0x891e3a0
[object instance proxy GIName:Geoclue.Master jsobj@0x8962460 native@0x88e98c0]
    JS G OBJ: Defining method create_client in prototype for GeoclueMaster (Geoclue.Master)
     JS G NS: Found info type OBJECT for 'MasterClient' in namespace 'Geoclue'
     JS G NS: Found info type OBJECT for 'MasterClient' in namespace 'Geoclue'
   JS G REPO: Initializing dynamic class MasterClient 0x894d4b0
    JS G OBJ: Defined class MasterClient prototype 0x89624e0 class 0x894d4b0 in object 0x8962380
[object instance proxy GIName:Geoclue.MasterClient jsobj@0x8962500 native@0x88e9980]
    JS G OBJ: Defining method create_position_async in prototype for GeoclueMasterClient (Geoclue.MasterClient)
 JS MAINLOOP: main loop  being run in context 0x88fcea8

** (gjs:10244): WARNING **: Metadata for error domain "geoclue-error-quark" already registered

     JS G NS: Found info type OBJECT for 'Position' in namespace 'Geoclue'
     JS G NS: Found info type OBJECT for 'Position' in namespace 'Geoclue'
     JS G NS: Found info type OBJECT for 'Provider' in namespace 'Geoclue'
   JS G REPO: Initializing dynamic class Provider 0x894d500
    JS G OBJ: Defined class Provider prototype 0x8962580 class 0x894d500 in object 0x8962380
   JS G REPO: Initializing dynamic class Position 0x894d550
    JS G OBJ: Defined class Position prototype 0x89625a0 class 0x894d550 in object 0x8962380
    JS ERROR: !!!   Unhandled type error converting GArgument to JavaScript
Comment 1 Morten Mjelva 2010-05-09 19:35:11 UTC
Created attachment 160660 [details]
source
Comment 2 Morten Mjelva 2010-05-09 19:35:33 UTC
Created attachment 160661 [details]
header
Comment 3 Owen Taylor 2010-05-09 19:57:19 UTC
Taking a GError as an in parameter is problematical because the way gjs handles errors is to convert them to exceptions. And you can't throw an exception *in* to a function.

The GIO approach of calling a function from within the callback works better for something like this.

typedef void (*GAsyncReadyCallback) (GObject *source_object,
                                     GAsyncResult *res,
                                     gpointer user_data);
void     g_file_replace_contents_async       (GFile                  *file,
                                              const char             *contents,
                                              gsize                   length,
                                              const char             *etag,
                                              gboolean                make_backup,
                                              GFileCreateFlags        flags,
                                              GCancellable           *cancellable,
                                              GAsyncReadyCallback     callback,
                                              gpointer                user_data);
gboolean g_file_replace_contents_finish      (GFile                  *file,
                                              GAsyncResult           *res,
                                              char                  **new_etag,
                                              GError                **error);
Comment 4 Dan Winship 2010-05-10 14:04:48 UTC
*** Bug 617495 has been marked as a duplicate of this bug. ***
Comment 5 Danielle Madeley 2010-05-11 00:24:50 UTC
Owen, that's all well and good, except when handling existing API there isn't a lot of choice.

I wrote a workaround for testing which just converts GI_TYPE_TAG_ERROR to JSVAL_NULL, but it should be possible (I would have thought) to convert it to a G_TYPE_ERROR boxed type, or a (domain, code, message) tuple, as well as pointing out to API designers, to stop designing APIs in this fashion.
Comment 6 Dan Winship 2010-05-11 01:41:14 UTC
(In reply to comment #5)
> Owen, that's all well and good, except when handling existing API there isn't a
> lot of choice.

The "Rename-to" annotation exists basically for exactly this problem (creating an alternative more-easily-wrapped version of a method without changing its C API).
Comment 7 Giovanni Campagna 2011-07-12 17:06:37 UTC
Created attachment 191824 [details] [review]
Add tests for callbacks with GErrors

GErrors in callbacks has to be handled differently than in other
functions (it cannot be mapped to exception handling facilities of
language runtimes). Add tests for that.
Comment 8 Giovanni Campagna 2011-07-12 17:09:14 UTC
Created attachment 191826 [details] [review]
Support callbacks that accept GErrors

Some async callbacks don't follow the GIO pattern and instead of
having a finish function, they embed the error directly in the
callback signature. Add support for that by wrapping the GError as
a boxed type.
Comment 9 Giovanni Campagna 2011-11-25 08:20:13 UTC
Any updates on this?
Comment 10 Giovanni Campagna 2012-08-26 11:39:43 UTC
I guess this is probably obsolete, now that we have full marshalling for GErrors.