-
-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: monkey patch Webmachine render_error method to support problem+…
…json (#584)
- Loading branch information
Showing
9 changed files
with
118 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
require "webmachine/errors" | ||
require "pact_broker/string_refinements" | ||
|
||
# Monkey patches the render_error method so that it returns hal+json or problem+json instead of text/html | ||
|
||
module Webmachine | ||
using PactBroker::StringRefinements | ||
|
||
# Renders a standard error message body for the response. The | ||
# standard messages are defined in localization files. | ||
# @param [Integer] code the response status code | ||
# @param [Request] req the request object | ||
# @param [Response] req the response object | ||
# @param [Hash] options keys to override the defaults when rendering | ||
# the response body | ||
def self.render_error(code, req, res, options={}) | ||
res.code = code | ||
unless res.body | ||
title, message = t(["errors.#{code}.title", "errors.#{code}.message"], | ||
{ :method => req.method, | ||
:error => res.error}.merge(options)) | ||
|
||
title = options[:title] if options[:title] | ||
message = options[:message] if options[:message] | ||
|
||
res.body = error_response_body(message, title, title.dasherize.gsub(/^\d+\-/, ""), code, req) | ||
res.headers[CONTENT_TYPE] = error_response_content_type(req) | ||
end | ||
ensure_content_length(res) | ||
ensure_date_header(res) | ||
end | ||
|
||
def self.problem_json_error_content_type?(request) | ||
request.headers["Accept"]&.include?("application/problem+json") | ||
end | ||
|
||
def self.error_response_content_type(request) | ||
if problem_json_error_content_type?(request) | ||
"application/problem+json;charset=utf-8" | ||
else | ||
"application/json;charset=utf-8" | ||
end | ||
end | ||
|
||
def self.error_response_body(detail, title, type, status, request) | ||
if problem_json_error_content_type?(request) | ||
PactBroker::Api::Decorators::CustomErrorProblemJSONDecorator.new(detail: detail, title: title, type: type, status: status).to_json | ||
else | ||
{ error: detail }.to_json | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require "webmachine/render_error_monkey_patch" | ||
|
||
module Webmachine | ||
describe ".render_error" do | ||
let(:request) { Webmachine::Request.new("GET", "http://example.org/foo", request_headers, "", {}) } | ||
let(:request_headers) { Webmachine::Headers.new } | ||
let(:response) { Webmachine::Response.new } | ||
let(:options) { {} } | ||
|
||
subject { Webmachine.render_error(404, request, response, options); response } | ||
|
||
it "returns a JSON body" do | ||
expect(JSON.parse(subject.body)).to eq "error" => "The requested document was not found on this server." | ||
end | ||
|
||
it "returns a json content-type" do | ||
expect(subject.headers["Content-Type"]).to eq "application/json;charset=utf-8" | ||
end | ||
|
||
context "when the Accept header contains application/problem+json" do | ||
let(:request_headers) { Webmachine::Headers.from_cgi("HTTP_ACCEPT" => "application/problem+json") } | ||
|
||
let(:expected_body) do | ||
{ | ||
"detail" => "The requested document was not found on this server.", | ||
"status" => 404, | ||
"title" => "404 Not Found", | ||
"type" => "/problem/not-found" | ||
} | ||
end | ||
|
||
it "returns a JSON body in problem json format" do | ||
expect(JSON.parse(subject.body)).to eq expected_body | ||
end | ||
|
||
context "with custom options" do | ||
let(:options) { { message: "hello world", title: "Title" } } | ||
|
||
let(:expected_body) do | ||
{ | ||
"detail" => "hello world", | ||
"status" => 404, | ||
"title" => "Title", | ||
"type" => "/problem/title" | ||
} | ||
end | ||
|
||
it "uses the custom message" do | ||
expect(JSON.parse(subject.body)).to eq expected_body | ||
end | ||
end | ||
end | ||
end | ||
end |