Method invocation error on v0.6

I have some code that looks like this:

route("/") do
  "hello"
end

Later on, the function passed into route is put in a variable to and the following code is run:

if isa(to, Function)
  to() |> to_response
end

Works perfectly on v0.5, but on v0.6 it throws an error

MethodError(#17, (), 0x000000000000598d)

I have no idea why as I can’t spot anything relevant in the NEWS for v0.6

Please help, I’ve been pulling my hair for the last 2 hours with this - once I run out of hair, my last resort is to crawl under my desk and cry as I’m running out of ideas.

Before you do that, please post more complete code and maybe the full error message.

1 Like

Thanks @yuyichao

Here are the relevant bits:

const _routes = Dict{Symbol,Any}()
const Route   = Tuple{Tuple{String,String,Union{String,Function}},Dict{Symbol,Dict{Any,Any}}}

function route(action::Function, path::String; method = GET, with::Dict = Dict{Symbol,Any}(), named::Symbol = :__anonymous_route) :: Route
  route(path, action, method = method, with = with, named = named)
end

function route(path::String, action::Union{String,Function}; method = GET, with::Dict = Dict{Symbol,Any}(), named::Symbol = :__anonymous_route) :: Route
  route_parts = (method, path, action)

  extra_route_parts = Dict(:with => with)
  named = named == :__anonymous_route ? route_name(route_parts) : named

  _routes[named] = (route_parts, extra_route_parts)
end

function routes() :: Vector{Route}
  collect(values(_routes))
end

function match_routes(req::Request, res::Response, session::Sessions.Session, params::Params) :: Response
  for r in routes()
    route_def, extra_params = r
    protocol, route, to = route_def

    # more code in here that doesn't matter

    return  try
              if isa(to, Function)
                to() |> to_response
              end
            catch ex
              Logger.log("Failed invoking controller", :err)
              Logger.log(string(ex), :err)
              Logger.log("$(@__FILE__):$(@__LINE__)", :err)

              rethrow(ex)
            end
  end
  serve_error_file(404, "Not found")
end

And the error:

2017-06-26T14:33:46.329 - critical: MethodError(#17, (), 0x0000000000005992)


2017-06-26T14:33:46.631 - critical:
Stacktrace:
 [1] match_routes(::HttpCommon.Request, ::HttpCommon.Response, ::Sessions.Session, ::Router.Params{Any}) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:461
 [2] route_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:86
 [3] handle_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:122
 [4] (::AppServer.##1#9)(::HttpCommon.Request, ::HttpCommon.Response) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:25
 [5] (::HttpServer.#on_message_complete#14{HttpServer.Server,HttpServer.Client{TCPSocket},Bool})(::HttpCommon.Request) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:427
 [6] on_message_complete(::Ptr{HttpParser.Parser}) at /Users/adrian/.julia/v0.6/HttpServer/src/RequestParser.jl:113
 [7] http_parser_execute(::HttpParser.Parser, ::HttpParser.ParserSettings, ::Array{UInt8,1}) at /Users/adrian/.julia/v0.6/HttpParser/src/HttpParser.jl:115
 [8] process_client(::HttpServer.Server, ::HttpServer.Client{TCPSocket}, ::Bool) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:389
 [9] (::HttpServer.##7#8{HttpServer.Server,Bool})() at ./task.jl:335

It seems that I get the error only in the context of executing the code through HttpServer :astonished:

This is what is looks like in my REPL - on top is the output from running a request through the browser. Then it’s me running the same code through the REPL.

2017-06-26T14:46:37.46 - error: Failed invoking controller


2017-06-26T14:46:37.46 - error: MethodError(#21, (), 0x0000000000005994)


2017-06-26T14:46:37.46 - error: /Users/adrian/.julia/v0.6/Genie/src/Router.jl:468


2017-06-26T14:46:37.461 - critical: MethodError(#21, (), 0x0000000000005994)


2017-06-26T14:46:37.491 - critical:
Stacktrace:
 [1] match_routes(::HttpCommon.Request, ::HttpCommon.Response, ::Sessions.Session, ::Router.Params{Any}) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:461
 [2] route_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:86
 [3] handle_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:122
 [4] (::AppServer.##1#9)(::HttpCommon.Request, ::HttpCommon.Response) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:25
 [5] (::HttpServer.#on_message_complete#14{HttpServer.Server,HttpServer.Client{TCPSocket},Bool})(::HttpCommon.Request) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:427
 [6] on_message_complete(::Ptr{HttpParser.Parser}) at /Users/adrian/.julia/v0.6/HttpServer/src/RequestParser.jl:113
 [7] http_parser_execute(::HttpParser.Parser, ::HttpParser.ParserSettings, ::Array{UInt8,1}) at /Users/adrian/.julia/v0.6/HttpParser/src/HttpParser.jl:115
 [8] process_client(::HttpServer.Server, ::HttpServer.Client{TCPSocket}, ::Bool) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:389
 [9] (::HttpServer.##7#8{HttpServer.Server,Bool})() at ./task.jl:335


2017-06-26T14:46:37.491 - critical: /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:29

genie> for r in Router.routes()
       route_def, extra_params = r
       protocol, route, to = route_def
       @show to()
       end
to() = "hello"

With a bit more debugging info

@show current_module()
if isa(to, Function)
  @show @which to()
  @show methods(to)
  @show to

  to() |> to_response
end

I get

current_module() = Main
@which(to()) = (::##17#18)() in Main at /Users/adrian/Dropbox/Projects/_test_app3/config/routes.jl:4
methods(to) = # 1 method for generic function "(::#17)":
(::##17#18)() in Main at /Users/adrian/Dropbox/Projects/_test_app3/config/routes.jl:4
to = #17

2017-06-26T14:59:53.217 - error: Failed invoking controller

2017-06-26T14:59:53.217 - error: MethodError(#17, (), 0x0000000000005992)

2017-06-26T14:59:53.218 - error: /Users/adrian/.julia/v0.6/Genie/src/Router.jl:473

2017-06-26T14:59:53.218 - critical: MethodError(#17, (), 0x0000000000005992)

2017-06-26T14:59:53.515 - critical:
Stacktrace:
 [1] match_routes(::HttpCommon.Request, ::HttpCommon.Response, ::Sessions.Session, ::Router.Params{Any}) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:466
 [2] route_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/Router.jl:86
 [3] handle_request(::HttpCommon.Request, ::HttpCommon.Response, ::IPv4) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:122
 [4] (::AppServer.##1#9)(::HttpCommon.Request, ::HttpCommon.Response) at /Users/adrian/.julia/v0.6/Genie/src/AppServer.jl:25
 [5] (::HttpServer.#on_message_complete#14{HttpServer.Server,HttpServer.Client{TCPSocket},Bool})(::HttpCommon.Request) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:427
 [6] on_message_complete(::Ptr{HttpParser.Parser}) at /Users/adrian/.julia/v0.6/HttpServer/src/RequestParser.jl:113
 [7] http_parser_execute(::HttpParser.Parser, ::HttpParser.ParserSettings, ::Array{UInt8,1}) at /Users/adrian/.julia/v0.6/HttpParser/src/HttpParser.jl:115
 [8] process_client(::HttpServer.Server, ::HttpServer.Client{TCPSocket}, ::Bool) at /Users/adrian/.julia/v0.6/HttpServer/src/HttpServer.jl:389
 [9] (::HttpServer.##7#8{HttpServer.Server,Bool})() at ./task.jl:335

I don’t get it… Julia knows that it is a function, it finds it, but then it can’t invoke it…

Likely HttpServer is not correctly executing the method in the latest world after eval code that defined the function. It should also showerror the error instead of just showing it’s content.

Thanks, I’ll open up an issue with HttpServer