Skip to content

Commit

Permalink
Accurately track any JSON Parser errors
Browse files Browse the repository at this point in the history
Provide the context of what JSON was received to Honeybadger and Raven
  • Loading branch information
justin808 committed May 14, 2018
1 parent fa52ac6 commit 5a9be34
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 10 deletions.
2 changes: 2 additions & 0 deletions lib/react_on_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require "rails"

require "react_on_rails/error"
require "react_on_rails/prerender_error"
require "react_on_rails/json_parse_error"
require "react_on_rails/react_on_rails_helper"
require "react_on_rails/controller"
require "react_on_rails/version"
Expand Down
26 changes: 26 additions & 0 deletions lib/react_on_rails/json_parse_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module ReactOnRails
class JsonParseError < ::ReactOnRails::Error
attr_reader :json

def initialize(parse_error, json)
@json = json
@original_error = parse_error
super(parse_error.message)
end

def to_honeybadger_context
to_error_context
end

def raven_context
to_error_context
end

def to_error_context
{
original_error: @original_error,
json: @json
}
end
end
end
24 changes: 15 additions & 9 deletions lib/react_on_rails/prerender_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ def raven_context
to_error_context
end

def to_error_context
result = {
component_name: component_name,
err: err,
props: props,
js_code: js_code,
console_messages: console_messages
}

if err.respond_to?(:to_error_context)
result.merge!(err.to_error_context)
end
result
end

private

def calc_message(component_name, console_messages, err, js_code, props)
Expand Down Expand Up @@ -60,14 +75,5 @@ def calc_message(component_name, console_messages, err, js_code, props)
[backtrace, message]
end

def to_error_context
{
component_name: component_name,
err: err,
props: props,
js_code: js_code,
console_messages: console_messages
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ def exec_server_render_js(js_code, render_options, js_evaluator = nil)
@file_index += 1
end
json_string = js_evaluator.eval_js(js_code)
result = JSON.parse(json_string)
result = nil
begin
result = JSON.parse(json_string)
rescue JSON::ParserError => e
raise ReactOnRails::JsonParseError.new(e, json_string)
end

if render_options.logging_on_server
console_script = result["consoleReplayScript"]
Expand Down
2 changes: 2 additions & 0 deletions spec/dummy/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

rescue_from ReactOnRails::PrerenderError do |err|
raise err if err.err.is_a?(ReactOnRails::JsonParseError)

Rails.logger.error("Caught ReactOnRails::PrerenderError in ApplicationController error handler.")
Rails.logger.error(err.message)
Rails.logger.error(err.backtrace.join("\n"))
Expand Down
10 changes: 10 additions & 0 deletions spec/dummy/spec/requests/server_render_check_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
.to eq("Mr. Server Side Rendering")
end

it "generates a prerender error if invalid JSON returned" do
invalid_json = "{ some invalid JSON"
allow(ReactOnRails::ServerRenderingPool::RubyEmbeddedJavaScript)
.to receive(:eval_js).and_return(invalid_json)
expect { get server_side_hello_world_with_options_path }.to(raise_error do |error|
expect(error.raven_context[:json]).to eq(invalid_json)
expect(error.raven_context[:original_error]).to be_instance_of(JSON::ParserError)
end)
end

it "generates server rendered HTML if server renderering enabled for shared redux" do
get server_side_hello_world_shared_store_path
html_nodes = Nokogiri::HTML(response.body)
Expand Down

0 comments on commit 5a9be34

Please sign in to comment.