# How to get backtrace of \`@async\` Task

**URL:** <https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170>\
**Category:** General Usage\
**Created:** [November 30, 2018, 3:56am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170 "2018-11-30T03:56:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![standarddeviant](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/standarddeviant/32/2309_2.png) [@standarddeviant](https://discourse.julialang.org/u/standarddeviant)\
**Post date:** [November 30, 2018, 3:56am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/1 "2018-11-30T03:56:55Z")

</div>

I’m unsure how to get the thrown error or backtrace of an asynchronous Task.

Here’s an example script:

```julia
# silent_test_all_in_one.jl

function do_some_work(increase::Real)
    a = 0.0
    start_time = time()
    while time() - start_time < 5
        b += increase
        sleep(0.1)
    end
    a
end

function start_blocking()
    println("start() is waiting for do_some_work() to be done")
    do_some_work(10)
end

function start_async()
    start_time = time()
    t = @async do_some_work(10)
    while !istaskdone(t)
        println("start() is waiting for do_some_work() to be done")
        sleep(1)
    end
end

```

To test, I did the following

1. Save that file as “silent\_test\_all\_in\_one.jl” and include it at the REPL
2. call `start_blocking` and see the appropriate error
3. call `start_async` and don’t see any indication of an error

```julia
julia> include("silent_test_all_in_one.jl")
start_async (generic function with 1 method)

julia> start_blocking()
start() is waiting for do_some_work() to be done
ERROR: UndefVarError: b not defined
Stacktrace:
 [1] do_some_work at C:\Users\dave\Documents\silent_test_all_in_one.jl:7 [inlined]
 [2] start_blocking() at C:\Users\dave\Documents\silent_test_all_in_one.jl:15
 [3] top-level scope at none:0

julia> start_async()
start() is waiting for do_some_work() to be done

julia> versioninfo()
Julia Version 1.0.2
Commit d789231e99 (2018-11-08 20:11 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, haswell)

```

Is this expected? Can this be avoided?

I’m working on a project that uses `HTTP.jl` to handle some requests asynchronously with Tasks. Often, the code “hangs” in the REPL and gives no feedback and that’s when I realized that asynchronous `Tasks`s don’t seem to print out thrown errors or backtraces when the code actually errors out.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [November 30, 2018, 8:32am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/2 "2018-11-30T08:32:22Z")

</div>

You can either print the error yourself or look at what the task resolves to:

```julia
function start_async_print()
    start_time = time()
    t = @async try
        do_some_work(10)
    catch err
        bt = catch_backtrace()
        println()
        showerror(stderr, err, bt)
    end
    while !istaskdone(t)
        println("start() is waiting for do_some_work() to be done")
        sleep(1)
    end
end

function start_async_throw()
    start_time = time()
    t = do_some_work(10)
    while !istaskdone(t)
        println("start() is waiting for do_some_work() to be done")
        sleep(1)
    end
    wait(t) # or fetch(t)
end

```

gives

```julia
julia> start_async_print()
start() is waiting for do_some_work() to be done

UndefVarError: b not defined
Stacktrace:
 [1] do_some_work at ./untitled-8822451613b5304f5f50924dadde5d27:6 [inlined]
 [2] (::getfield(Main, Symbol("##27#28")))() at ./task.jl:259
julia> start_async_throw()
ERROR: UndefVarError: b not defined
Stacktrace:
 [1] do_some_work at ./untitled-8822451613b5304f5f50924dadde5d27:6 [inlined]
 [2] start_async_throw() at ./untitled-8822451613b5304f5f50924dadde5d27:33
 [3] top-level scope at none:0

```

The `wait`/`fetch` approach obviously doesn’t work very well when you don’t want to block.

---

<div class="post-metadata">

**Author:** ![standarddeviant](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/standarddeviant/32/2309_2.png) [@standarddeviant](https://discourse.julialang.org/u/standarddeviant)\
**Post date:** [November 30, 2018, 11:03am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/3 "2018-11-30T11:03:06Z")

</div>

Thank you! Is there a good way to encapsulate that behavior in a new macro? This seems to work:

```julia
macro async_showerr(ex)
    quote
        t = @async try
            eval($(esc(ex)))
        catch err
            bt = catch_backtrace()
            println()
            showerror(stderr, err, bt)
        end
    end
end

```

But is there a downside to using a macro like this?

---

<div class="post-metadata">

**Author:** ![standarddeviant](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/standarddeviant/32/2309_2.png) [@standarddeviant](https://discourse.julialang.org/u/standarddeviant)\
**Post date:** [December 1, 2018, 1:49pm UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/4 "2018-12-01T13:49:46Z")

</div>

@pfitzseb I’m curious why `@async` doesn’t do this automatically and I’m trying to imagine the downsides.

This seems like an easily avoidable trap for newbies. For more advanced users who want the current behavior explicitly, they could call a macro like `@async_silent`.

Does that make sense?

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [October 25, 2020, 8:56am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/5 "2020-10-25T08:56:04Z")

</div>

This is an old topic, but I have the very same issue with async tasks: they don’t show a useful stacktrace be default. Not only `@async` itself, but also e.g. `asyncmap`:

```julia
asyncmap(0:10) do i
    1 ÷ i
end

ERROR: DivideError: integer division error
Stacktrace:
 [1] (::Base.var"#770#772")(::Task) at ./asyncmap.jl:178
 [2] foreach(::Base.var"#770#772", ::Array{Any,1}) at ./abstractarray.jl:2009
 [3] maptwice(::Function, ::Channel{Any}, ::Array{Any,1}, ::UnitRange{Int64}) at ./asyncmap.jl:178
 [4] wrap_n_exec_twice at ./asyncmap.jl:154 [inlined]
 [5] #async_usemap#755 at ./asyncmap.jl:103 [inlined]
 [6] #asyncmap#754 at ./asyncmap.jl:81 [inlined]
 [7] asyncmap(::Function, ::UnitRange{Int64}) at ./asyncmap.jl:81
 [8] top-level scope at REPL[3]:1

```

compare to `map`:

```julia
map(0:10) do i
    1 ÷ i
end

ERROR: DivideError: integer division error
Stacktrace:
 [1] div at ./int.jl:260 [inlined]
 [2] #13 at ./REPL[4]:2 [inlined]
 [3] iterate at ./generator.jl:47 [inlined]
 [4] _collect(::UnitRange{Int64}, ::Base.Generator{UnitRange{Int64},var"#13#14"}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./array.jl:699
 [5] collect_similar(::UnitRange{Int64}, ::Base.Generator{UnitRange{Int64},var"#13#14"}) at ./array.jl:628
 [6] map(::Function, ::UnitRange{Int64}) at ./abstractarray.jl:2162
 [7] top-level scope at REPL[4]:1

```

Is there any way to force the stacktrace go further than the `asyncmap` internals, i.e. to the actual user function? I can only imagine putting `try ... catch ... end` there manually.

---

<div class="post-metadata">

**Author:** ![airpmb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/airpmb/32/7826_2.png) [@airpmb](https://discourse.julialang.org/u/airpmb)\
**Post date:** [January 21, 2021, 9:06pm UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/6 "2021-01-21T21:06:44Z")

</div>

Wondering in the same thing; I very much got snared in this newbie trap.

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [February 2, 2023, 9:43am UTC](https://discourse.julialang.org/t/how-to-get-backtrace-of-async-task/18170/7 "2023-02-02T09:43:41Z")

</div>

There’s an [`errormonitor`](https://docs.julialang.org/en/v1/base/parallel/#Base.errormonitor) function to print errors thrown in an `@async` task.

```julia
julia> errormonitor(@async (sleep(1.0); error("bla")))
Task (runnable) @0x00007fbe2ae5bb70

julia> Unhandled Task ERROR: bla
Stacktrace:
 [1] error(s::String)

```
