Skip to content

Proper way to use before and rescue_from defined within other module? #122

@mrusme

Description

@mrusme

I'm struggling to figure out how to make use of of things like before and rescue_from when they are defined inside another module, e.g.:

ExternalModule

defmodule ExternalModule.Server do
    defmacro __using__(_) do
        quote do
            use Maru.Server, otp_app: Confex.fetch_env!(:external_module, :server)[:app]

            def init(_type, opts) do
                Confex.Resolver.resolve(opts)
            end
        end
    end
end
defmodule ExternalModule do
    import Plug
    use ExternalModule.Server
    use ExternalModule.Helpers.Response

    defmacro __using__(_) do
        quote do
            before do
                plug Plug.Logger
                plug Corsica, origins: "*"
                plug Plug.Parsers,
                    pass: ["*/*"],
                    json_decoder: Jason,
                    parsers: [:urlencoded, :json, :multipart]
            end

            rescue_from Unauthorized, as: e do
                IO.inspect e
                ...
            end

            rescue_from [MatchError, RuntimeError], as: e do
                IO.inspect e
                ...
            end

            rescue_from Maru.Exceptions.InvalidFormat, as: e do
                IO.inspect e
                ...
            end

            rescue_from Maru.Exceptions.NotFound, as: e do
                IO.inspect e
                ...
            end

            rescue_from :all, as: e do
                IO.inspect e
                ...
            end
        end
    end
end

Now, inside my project I add ExternalModule as a dependency I and I create the following files:

MyModule

use Mix.Config

config :my_module, MyModule.Server,
    adapter: Plug.Cowboy,
    plug: MyModule.API,
    scheme: :http,
    ip: {0,0,0,0},
    port: {:system, :integer, "PORT", 8882}

config :my_module,
    maru_servers: [MyModule.Server]

config :external_module, :server,
    app: :my_module
defmodule MyModule.Server do
    use ExternalModule.Server
end
defmodule MyModule.API do
    use ExternalModule
    use MyModule.Server

    resources do
        get do
            json(conn, %{hello: :world})
        end

        mount MyModule.API.EndpointOne
    end
end

The application compiles successfully, but when I'm trying to access the endpoint that should be mounted with MyModule.API.EndpointOne a 500 is being returned. Apparently the mount is being ignores, as are the rescue_from definitions within the ExternalModule. However, the get do that returns hello: :world is being run when performing a GET /.

I'm not sure if this is a bug or simply me holding it wrong. However, some help (and maybe documentation) on this topic would be very much appreciated! :-)

Thanks!

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