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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions