Skip to content

StandardErrors are swallowed #230

Closed
Closed

Description

@kwerle

I'm adding async and I love it so far - with one exception: exceptions. Well, those that are StandardErrors, anyway. Async swallows them.

task.rb:314:

rescue StandardError => error
  failed!(error, false)

That false says to not re-raise it. So the task exits and says there "might have been" an exception and gives the backtrace - all of which is helpful - but not enough. Ideally I would like it to treat StandardErrors the same way as Exceptions. At the least I want some way to get at the swallowed exceptions so I can re-raise them myself.

I'm happy to code a solution - including passing a parameter to Async do -- Async(error_handling: :reraise) do, or something like that.

Activity

  1. trevorturk commented on Apr 28, 2023

    @trevorturk
    Contributor

    This is definitely easy to get tripped up on, and it's one of the more confusing aspects of Async, IMO, but I think it all makes sense eventually!

    There's a bit of documentation around exceptions worth reading, you can check this out to get started: https://socketry.github.io/async/guides/asynchronous-tasks/index.html#exception-handling

    Let me know what you think, and if you have more questions I can try to help, or I'm sure someone else can chime in as well!

  2. kwerle commented on Apr 28, 2023

    @kwerle
    Author

    Super helpful - thanks. I was doing something wrong, and I'm still not super happy with what I have to do.

    My mistake:

    Async do
      Fiber.schedule do
        ...
      end
      Fiber.schedule do
        ...
      end
    end
    

    Because I was using Fiber.schedule directly I had no access to the exceptions. That's my mistake and it happened because I was migrating to async and failed to convert the schedule calls.

    What I have to do:

    tasks = []
    Async do
      tasks << Async do
        ...
      end
      tasks << Async do
        ...
      end
    end
    tasks.each(&:wait)
    

    This is sufficient. But I would still prefer something more streamlined:

    Async(raise_errors: true) do
      Async do
        ...
      end
      Async do
        ...
      end
    end
    

    Or perhaps (if the outer can keep track of the internal fibers)

    Async do
      Async do
        ...
      end
      Async do
        ...
      end
    end.reraise_errors
    

    Having to gather and call wait to re-raise isn't at all intuitive. If I were coming to the code as a new user, I would probably assume the wait was needed to get the fibers to execute - not that it was being used to handle errors!

  3. trevorturk commented on Apr 28, 2023

    @trevorturk
    Contributor

    I use a barrier for this, since it collects the tasks in a "bucket" I can call wait on, but, yeah, dealing with exceptions is a bit more verbose. I suppose I don't think about it much anymore, once I got accustomed to it, tbh.

  4. ioquatix commented on Apr 28, 2023

    @ioquatix
    Member

    A task may outlive it's parent so the parent can't naturally be a scope for exception handling.

    I think ideally, tasks don't raise exceptions as a matter of normal behaviour ("exceptional" cases).

    Either you are waiting on a task to complete (fan out) or you are "fire and forget". You need to think about what situation you are in and what is the appropriate error handling for your situation.

    As @trevorturk suggested, using an Async::Barrier is a good option for fan-out. https://socketry.github.io/async/source/Async/Barrier/index.html

  5. locked and limited conversation to collaborators on Jun 4, 2023
  6. converted this issue into a discussion #239 on Jun 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions