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 623210 - Async blocks
Async blocks
Status: RESOLVED OBSOLETE
Product: vala
Classification: Core
Component: Async
unspecified
Other All
: Normal enhancement
: 2.0
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2010-06-30 13:33 UTC by Philip Withnall
Modified: 2018-05-22 13:39 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Philip Withnall 2010-06-30 13:33:03 UTC
If I have a sync function calling an async function, Vala will generate a call to the async function, passing NULL for the callback. If I want to ignore the result of the async function, _but_ want to handle any errors which are thrown by it, I currently have to write the following:

public void sync_function ()
{
  async_function.begin ((obj, result) =>
    {
      try
        {
          async_function.end (result);
        }
      catch (GLib.Error e)
        {
          warning ("Error with async function: %s", e.message);
        }
    });
}

It would be a lot nicer if I could just write the following:

public void sync_function()
{
  try
    {
      async_function ();
    }
  catch (GLib.Error e)
    {
      warning ("Error with async function: %s", e.message);
    }
}

At the moment, Vala just complains about an unreachable catch block, and it passes NULL as the async function's callback.
Comment 1 Jürg Billeter 2010-06-30 15:54:44 UTC
(In reply to comment #0)
> It would be a lot nicer if I could just write the following:
> 
> public void sync_function()
> {
>   try
>     {
>       async_function ();
>     }
>   catch (GLib.Error e)
>     {
>       warning ("Error with async function: %s", e.message);
>     }
> }
> 
> At the moment, Vala just complains about an unreachable catch block, and it
> passes NULL as the async function's callback.

This doesn't make sense when looking at the code logic. The sync_function finishes execution before the async_function returns, therefore also all try/catch blocks in that method have already been executed and it's impossible to catch the error before the async_function returns.

An alternative possibility is to use Vala's async method support. This requires a helper function, though:

async void call_async () {
    try {
        yield async_function ();
    } catch (Error e) {
        warning...
    }
}

void sync_function () {
    call_async ();
}

Maybe it would make sense to introduce the concept of async blocks to simplify this as follows:

void sync_function () {
    async {
        try {
            yield async_function ();
        } catch (Error e) {
            warning...
        }
    }
}

Any comments?
Comment 2 Philip Withnall 2010-06-30 16:05:27 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > It would be a lot nicer if I could just write the following:
> > 
> > public void sync_function()
> > {
> >   try
> >     {
> >       async_function ();
> >     }
> >   catch (GLib.Error e)
> >     {
> >       warning ("Error with async function: %s", e.message);
> >     }
> > }
> > 
> > At the moment, Vala just complains about an unreachable catch block, and it
> > passes NULL as the async function's callback.
> 
> This doesn't make sense when looking at the code logic. The sync_function
> finishes execution before the async_function returns, therefore also all
> try/catch blocks in that method have already been executed and it's impossible
> to catch the error before the async_function returns.

The idea was that the catch block would magically be put into the AsyncReadyCallback for the async function, making the try...catch block apply to the whole period of execution of the async function.

However, the way you describe it, I can see how that wouldn't make sense from a code flow point of view.

> An alternative possibility is to use Vala's async method support. This requires
> a helper function, though:
> 
> async void call_async () {
>     try {
>         yield async_function ();
>     } catch (Error e) {
>         warning...
>     }
> }
> 
> void sync_function () {
>     call_async ();
> }

The objective was to reduce the amount of code needed to do this, since I've found myself doing it a lot in my code. This is neater than my solution, but not really more concise. :-(

> Maybe it would make sense to introduce the concept of async blocks to simplify
> this as follows:
> 
> void sync_function () {
>     async {
>         try {
>             yield async_function ();
>         } catch (Error e) {
>             warning...
>         }
>     }
> }
> 
> Any comments?

That's neat. :-) I guess any code after the async block would be magically moved to the async block's ready callback?
Comment 3 Jürg Billeter 2010-06-30 16:10:05 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > Maybe it would make sense to introduce the concept of async blocks to simplify
> > this as follows:
> > 
> > void sync_function () {
> >     async {
> >         try {
> >             yield async_function ();
> >         } catch (Error e) {
> >             warning...
> >         }
> >     }
> > }
> > 
> > Any comments?
> 
> That's neat. :-) I guess any code after the async block would be magically
> moved to the async block's ready callback?

No, code after the async block would be normal part of the sync_function and executed right after starting the execution of the async block. Or did you mean after the try block?
Comment 4 Philip Withnall 2010-06-30 16:35:56 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #1)
> > > Maybe it would make sense to introduce the concept of async blocks to simplify
> > > this as follows:
> > > 
> > > void sync_function () {
> > >     async {
> > >         try {
> > >             yield async_function ();
> > >         } catch (Error e) {
> > >             warning...
> > >         }
> > >     }
> > > }
> > > 
> > > Any comments?
> > 
> > That's neat. :-) I guess any code after the async block would be magically
> > moved to the async block's ready callback?
> 
> No, code after the async block would be normal part of the sync_function and
> executed right after starting the execution of the async block. Or did you mean
> after the try block?

No, I meant after the async block, but you're right.
Comment 5 GNOME Infrastructure Team 2018-05-22 13:39:58 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/vala/issues/114.