Bukdu.jl icon indicating copy to clipboard operation
Bukdu.jl copied to clipboard

[RFC] Allow to override de SystemController methods

Open lucianolorenti opened this issue 5 years ago • 2 comments
trafficstars

I added the possibility to change the functions of the SystemController when an exception occurs. In case you want a custom controller when a plug halt the execution you can use

import Bukdu.System: halted_error, HaltedError
halted_error(c::W, err::HaltedError) = Bukdu.render(Bukdu.JSON, "Custom Halted Error")

Similarly with the not_applicable or internal_error

lucianolorenti avatar Apr 10 '20 00:04 lucianolorenti

thanks for contribution! hmm, but you could just override the functions on Bukdu.System. do you really need the custom errors for each controller?

using Test
using Bukdu
using .Bukdu.System

function Bukdu.System.internal_error(c::System.SystemController)
    c.conn.request.response.status = 500 # 500 Internal Server Error
    render(HTML, "Custom Internal Error")
end

function Bukdu.System.not_applicable(c::System.SystemController)
    c.conn.request.response.status = 500 # 500 Internal Server Error
    render(HTML, "Custom Not Applicable Error")
end

function Bukdu.System.halted_error(::System.SystemController)
    render(HTML, "Custom Halted Error")
end

struct IndexController <: ApplicationController
    conn::Conn
end

error_function(::IndexController) = throw("Some error")
something_not_applicable() = nothing
halted_function(::IndexController) = :ok

function test_custom_errors()
    routes() do
        get("/error", IndexController, error_function)
        get("/not_a", IndexController, something_not_applicable)
    end
    pipeline(:halted) do conn::Conn
        conn.request.response.status = 401 # 401 Unauthorized
        conn.halted = true
    end
    routes(:halted) do
        get("/halted", IndexController, halted_function)
    end
    response = Router.call(get, "/error")
    @test response.got == "Custom Internal Error"
    response = Router.call(get, "/not_a")
    @test response.got == "Custom Not Applicable Error"
    response = Router.call(get, "/halted")
    @test response.got == "Custom Halted Error"
end
test_custom_errors()

wookay avatar Apr 10 '20 03:04 wookay

In my use case, I wanted to have a different halted_function caused by a halted pipeline. In case of unauthorized access, I wanted that the rest API performs some action, return something that indicates it. And if a get request was performed in a privileged page I wanted to redirect to some other page.

EDIT: I think I found a workaround without modifying the code. Maybe I won't need this at all.

lucianolorenti avatar Apr 10 '20 15:04 lucianolorenti