# How to use debugger with HTTP.jl

**URL:** <https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248>\
**Category:** General Usage\
**Created:** [May 15, 2019, 5:53pm UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248 "2019-05-15T17:53:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [May 15, 2019, 5:53pm UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/1 "2019-05-15T17:53:30Z")

</div>

I’ve been struggling to use the new debugging tools with HTTP but I can’t get it to work. Take this simple example:

```julia
using HTTP, Sockets

function handleReq(req)
  "200 OK"
end

HTTP.serve(ip"127.0.0.1", 8000, verbose = true, rate_limit = nothing) do req::HTTP.Request
  handleReq(req)
end

```

I tried everything I could think of but I can’t get the debugger session to start when entering the handler or on error.

---

<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:** [May 15, 2019, 6:22pm UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/2 "2019-05-15T18:22:21Z")

</div>

```julia
julia> using HTTP, Sockets, Debugger

julia> function handleReq(req)
         error("nope")
         "200 OK"
       end
handleReq (generic function with 1 method)

julia> Debugger.break_on(:error)

julia> HTTP.serve(ip"127.0.0.1", 8000, verbose = true, rate_limit = nothing) do req::HTTP.Request
         @run handleReq(req)
       end
[ Info: Listening on: 127.0.0.1:8000
[ Info: Accept (1): 🔗 0↑ 0↓ 1s 127.0.0.1:8000:8000 ≣16
Breaking for error:
ERROR: nope
Stacktrace:
 [1] error(::String) at error.jl:33
 [2] handleReq(::HTTP.Messages.Request) at REPL[2]:2

In error(s) at error.jl:33
>33 error(s::AbstractString) = throw(ErrorException(s))

About to run: (throw)(ErrorException("nope"))
1|debug> bt
[1] error(s) at error.jl:33
  | s::String = "nope"
[2] handleReq(req) at REPL[2]:2
  | req::HTTP.Messages.Request = <suppressed 344 bytes of output>

```

The important thing to remember is that you need to have a `@run` or `@enter` statement _somewhere_ for the debugger to become active.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [May 15, 2019, 6:40pm UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/3 "2019-05-15T18:40:09Z")

</div>

Excellent, thanks so much!

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [May 16, 2019, 7:16am UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/4 "2019-05-16T07:16:58Z")

</div>

Although it technically works, it seems to fail consistently in real-life scenarios.

My objective was to get this working with Genie apps, where this `handleReq` function does a lot of complex work. So it would be something like:

```julia
function handleReq()
  response = a_lot_of_deep_nested_computations()
  return response 
end

```

When passing this through the debugger, two things happen:

1 - it is unbearably slow, to the point of not being usable;

2 - breaking on error, deep in the computation, starts a debug session. Quitting the debug session returns `nothing`. Which raises another exception because `response` should not be `nothing`. Which is being caught again, and so on - it just never seems to exit the debugger which is amplified by being so slow and unresponsive to the point of having to quit the whole thing.

* * *

So another approach I took was to load the debugger a lot later within the `a_lot_of_deep_nested_computations()` stack. Something in the line of:

```julia
function a_lot_of_deep_nested_computations()
  a(
    b(
      c(
        # more stuff happening
        Debugger.@run user_generated_code_to_be_debugged()
      )
    )
  )
end

```

That works much better, performance wise, but the debugger goes nuts. It doesn’t properly process the input, any input is interpreted like garbage:

```julia
1|debug>
Unknown command `lphfea`. Executing `?` to obtain help.

1|debug> lphttt?
Unknown command `lphttt?`. Executing `?` to obtain help.

```

Sometimes it falls down to the julian REPL with garbage, then back to debug:

```julia
julia> i_tsss
ERROR: UndefVarError: i_tsss not defined

1|debug>
Unknown command `lphfea`. Executing `?` to obtain help.

```

* * *

I can’t comment on the technicalities as I’m not familiar with the debugger (nor with the debugging process too much), but I guess we can conclude that:

a. it doesn’t seem to work well across spawned processes;

b. it’s not flexible enough - due to its performance penalty, there should be a global flag to disable all debugging. For instance, I’d be happy to use it in development but automatically disable it in production. A global flag like Revise has would be very useful, which would turn the call to `@run` to doing nothing. This would allow having `@run` in the codebase without the risk of breaking the app in production or having to chase down all the calls before release.

c. there’s an issue with returning `nothing` from the debug session - this raises more exceptions if the calling function does not expect `nothing`.

d. the interpreter is still too slow for randomly complex computations.

e. a `@debug` helper to make code debuggable would be useful. For instance, in a module like this, which is a `Controller`, the `index()` function is automatically invoked by the framework:

```julia
module BooksController

using Debugger
Debugger.break_on(:error)

function index()
  a()
  b()
  c()
end

# more code

```

To make it debuggable I need to do something like:

```julia
function index()
  function debuggable_index()
    a()
    b()
    c()
  end
  Debugger.@run debuggable_index()
end

```

I would be nice to just say `@debug` and have the function modified for debugging:

```julia
@debug function index()
  # code
end

```

* * *

Thanks, I hope it makes sense.

---

<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:** [May 16, 2019, 7:30am UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/5 "2019-05-16T07:30:28Z")

</div>

> [@essenciary](#):
>
> a. it doesn’t seem to work well across spawned processes;

That’s a known issue I think (and might also be where the junk in your REPL comes from).

> [@essenciary](#):
>
> b. it’s not flexible enough - due to its performance penalty, there should be a global flag to disable all debugging. For instance, I’d be happy to use it in development but automatically disable it in production. A global flag like Revise has would be very useful, which would turn the call to `@run` to doing nothing. This would allow having `@run` in the codebase without the risk of breaking the app in production or having to chase down all the calls before release.

That seems like something you should be able to code yourself? Or just write a convenience macro that looks at a global const to enable/disable interpreting your code.

> [@essenciary](#):
>
> c. there’s an issue with returning `nothing` from the debug session - this raises more exceptions if the calling function does not expect `nothing` .

If you take a look at the help you’ll see both

```plaintext
  - c: continue execution until a breakpoint is hit
  - q: quit the debugger, returning nothing

```

so try the `c` instead of `q` (which ungracefully shuts down everything, basically).

> [@essenciary](#):
>
> d. the interpreter is still too slow for randomly complex computations.

True. This will get better if someone has time to work on performance (although the interpreter typically isn’t _that_ slow there probably are edge cases where you’ll see a slow down of a couple of orders of magnitude), but in the meantime you can play around with toggling compiled mode with

```plaintext
 - C: toggle compiled mode

```

Do note that breakpoints don’t work in compiled mode, so it’s only useful for stepping.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [May 16, 2019, 7:40am UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/6 "2019-05-16T07:40:55Z")

</div>

@pfitzseb Thank you!

Sure, happy to contribute - just wanted to make sure that it’s not something isolated to my instance or me doing something wrong.

I’ve also added a point `e.`, the `@debug` macro. Do you think that makes sense or am I approaching the debugging process incorrectly and there’s an easier way to make a function debuggable when the function can not be called directly.

---

<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:** [May 16, 2019, 8:19am UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/7 "2019-05-16T08:19:13Z")

</div>

> [@essenciary](#):
>
> e. a `@debug` helper to make code debuggable would be useful. For instance, in a module like this, which is a `Controller` , the `index()` function is automatically invoked by the framework:
> 
> ```julia
> module BooksController
> 
> using Debugger
> Debugger.break_on(:error)
> 
> function index()
> a()
> b()
> c()
> end
> 
> # more code
> 
> ```
> 
> To make it debuggable I need to do something like:
> 
> ```julia
> function index()
> function debuggable_index()
> a()
> b()
> c()
> end
> Debugger.@run debuggable_index()
> end
> 
> ```
> 
> I would be nice to just say `@debug` and have the function modified for debugging:
> 
> ```julia
> @debug function index()
> # code
> end
> 
> ```

Yeah, right now that’s probably the best way to do this. I don’t think there’s a fundamental reason why `@run` can’t support arbitrary expressions, including

```julia
function index()
  @run begin
    foo()
    bar()
  end
end

```

blocks.

In general I’d suggest having the `@run` invocation further towards the original entry point, but if performance is prohibitively bad (do open an issue with a MWE if that’s the case!) then you don’t have much of a choice.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [May 16, 2019, 6:14pm UTC](https://discourse.julialang.org/t/how-to-use-debugger-with-http-jl/24248/8 "2019-05-16T18:14:23Z")

</div>

Makes sense, thank you!
