Skip to content

Commit

Permalink
Decouple from HTTP::Server::Context (#49)
Browse files Browse the repository at this point in the history
* Decouple exception page from `HTTP::Server::Context`

* Give defaults to collection properties
Add test case
  • Loading branch information
Blacksmoke16 authored Jul 15, 2024
1 parent ed04897 commit 32ef885
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class MyErrorHandler
raise SomeError.new("Something went wrong")
rescue e
context.response.status_code = 500
context.response.print MyApp::ExceptionPage.for_runtime_exception(context, e).to_s
context.response.print MyApp::ExceptionPage.new context, e
end
end
```
Expand Down
4 changes: 4 additions & 0 deletions spec/exception_page_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ describe ExceptionPage do
flow.view_error_page
flow.should_have_additional_message_lines
end

it "allows instantiating one manually" do
MyApp::ExceptionPage.new Exception.new("Oh noes"), "SEARCH", "/users", :im_a_teapot
end
end

class ErrorDebuggingFlow < LuckyFlow
Expand Down
4 changes: 2 additions & 2 deletions spec/support/test_handler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ class TestHandler
raise CustomException.new("Something went very wrong\nBut wait, there's more!")
rescue e : CustomException
context.response.content_type = "text/html"
context.response.print MyApp::ExceptionPage.for_runtime_exception(context, e)
context.response.print MyApp::ExceptionPage.new context, e
end
else
begin
raise CustomException.new("Something went very wrong")
rescue e : CustomException
context.response.content_type = "text/html"
context.response.print MyApp::ExceptionPage.for_runtime_exception(context, e)
context.response.print MyApp::ExceptionPage.new context, e
end
end
end
Expand Down
81 changes: 43 additions & 38 deletions src/exception_page.cr
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,57 @@ abstract class ExceptionPage
"all"
end
end

def host_from_context(context)
if host = context.request.headers["Host"]?
host = "http://#{host}"
end
host
end
end

include Helpers

@params : Hash(String, String)
@headers : Hash(String, Array(String))
@session : Hash(String, HTTP::Cookie)
def self.new(context : HTTP::Server::Context, exception : Exception)
new(
exception,
context.request.method,
context.request.path,
context.response.status,
nil,
context.request.query_params,
context.response.headers,
context.response.cookies,
exception.message,
)
end

@method : String
@path : String
@status : HTTP::Status
@title : String
@params : URI::Params
@headers : HTTP::Headers
@cookies : HTTP::Cookies?
@message : String
@query : String
@url : String
@frames : Array(Backtracer::Backtrace::Frame)
@title : String

def initialize(
exception : Exception,
@method : String,
@path : String,
@status : HTTP::Status,
title : String? = nil,
@params : URI::Params = URI::Params.new,
@headers : HTTP::Headers = HTTP::Headers.new,
@cookies : HTTP::Cookies = HTTP::Cookies.new,
message : String? = nil,
url : String? = nil
)
@title = title || "An Error Occurred: #{@status.description}"
@message = message || "Something went wrong"
@url = url || "#{@headers["host"]?}#{@path}"

@frames = if exception.backtrace?
Backtracer.parse(exception.backtrace, configuration: backtracer).frames
else
[] of Backtracer::Backtrace::Frame
end
end

abstract def styles : Styles

Expand All @@ -68,32 +99,6 @@ abstract class ExceptionPage
def backtracer : Backtracer::Configuration?
end

# :nodoc:
def initialize(context : HTTP::Server::Context, @message, @title, @frames)
@params = context.request.query_params.to_h
@headers = context.response.headers.to_h
@method = context.request.method
@path = context.request.path
@url = "#{host_from_context(context)}#{context.request.path}"
@query = context.request.query_params.to_s
@session = context.response.cookies.to_h
end

def initialize(context : HTTP::Server::Context, ex : Exception)
title = "Error #{context.response.status_code}"
frames =
if ex.backtrace?
Backtracer.parse(ex.backtrace, configuration: backtracer).frames
else
[] of Backtracer::Backtrace::Frame
end
initialize(context, ex.message.to_s, title: title, frames: frames)
end

def self.for_runtime_exception(context : HTTP::Server::Context, ex : Exception)
new(context, ex)
end

ECR.def_to_s "#{__DIR__}/exception_page/exception_page.ecr"
end

Expand Down
10 changes: 5 additions & 5 deletions src/exception_page/exception_page.ecr
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@

<dl>
<dt>Query string:</dt>
<dd class="code-quote"><%= HTML.escape(@query) %></dd>
<dd class="code-quote"><%= HTML.escape(@params.to_s) %></dd>
</dl>
</details>

Expand All @@ -827,13 +827,13 @@
<% end %>
</details>

<% if (session = @session) && !session.empty? %>
<% if (cookies = @cookies) && !cookies.empty? %>
<details class="conn-details">
<summary>Session</summary>
<% session.each do |key, value| %>
<% cookies.each do |cookie| %>
<dl>
<dt><%= HTML.escape(key) %></dt>
<dd><pre><%= HTML.escape(value.inspect) %></pre></dd>
<dt><%= HTML.escape(cookie.name) %></dt>
<dd><pre><%= HTML.escape(cookie.value.inspect) %></pre></dd>
</dl>
<% end %>
</details>
Expand Down

0 comments on commit 32ef885

Please sign in to comment.