From a715becca38951452bd303da136510ef947d82a9 Mon Sep 17 00:00:00 2001 From: syeopite Date: Sun, 14 Nov 2021 08:37:50 -0800 Subject: [PATCH] Add special error page for InitialInnerTubeParseException --- src/invidious/errors/errors.cr | 3 ++ src/invidious/errors/special_exceptions.cr | 45 ++++++++++++++++++++-- src/invidious/yt_backend/youtube_api.cr | 21 +++++++++- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/invidious/errors/errors.cr b/src/invidious/errors/errors.cr index 2a9cbefd..3f7bfe8e 100644 --- a/src/invidious/errors/errors.cr +++ b/src/invidious/errors/errors.cr @@ -15,8 +15,11 @@ def github_details_backtrace(summary : String, content : String) end def generic_error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception) + # Custom error routing if exception.is_a?(InfoException) return generic_error_template_helper(env, locale, status_code, exception.message || "") + elsif exception.is_a? InitialInnerTubeParseException + return exception.error_template_helper(env, locale) end env.response.content_type = "text/html" diff --git a/src/invidious/errors/special_exceptions.cr b/src/invidious/errors/special_exceptions.cr index 86ac679a..dac4ebc0 100644 --- a/src/invidious/errors/special_exceptions.cr +++ b/src/invidious/errors/special_exceptions.cr @@ -14,10 +14,49 @@ end # the error page for debugging/research purposes. # class InitialInnerTubeParseException < Exception - # temporally place holder - def self.new(parse_exception, **kwargs) + def initialize(@endpoint : String, @client_config : String, @data : String, @status_code : Int32, @mime_type : String, @cause : Exception) + end + + def self.new(parse_exception : Exception, + endpoint : String, + client_config : String, + data : String, + status_code : Int32, + mime_type : String) instance = InitialInnerTubeParseException.allocate - instance.initialize(error_message, parse_exception) + instance.initialize(endpoint, client_config, data, status_code, mime_type, cause: parse_exception) return instance end + + private def render_innertube_metadata_section(locale) + contents = %(\n\n
) + contents += %(\nInnerTube request metadata) + contents += %(\n

\n) + contents += %(\n \n```\n) + + contents += %(Endpoint: `#{@endpoint}`\n) + contents += %(\nClient config: ```json\n#{@client_config}\n```\n) + contents += %(\nData: ```json\n#{@data}\n```\n) + contents += %(\nStatus code: `#{@status_code}`\n) + contents += %(MIME type: `#{@mime_type}`) + + contents += %(\n```) + contents += %(\n

) + contents += %(\n
) + + return HTML.escape(contents) + end + + def error_template_helper(env, locale) + env.response.content_type = "text/html" + env.response.status_code = 500 + + # HTML rendering. + exception = @cause.not_nil! + backtrace = github_details_backtrace("Backtrace", @cause.not_nil!.inspect_with_backtrace) + backtrace += render_innertube_metadata_section(locale) + error_message = rendered "error_pages/generic" + + return templated "error_pages/generic_wrapper" + end end diff --git a/src/invidious/yt_backend/youtube_api.cr b/src/invidious/yt_backend/youtube_api.cr index 27f25036..0f94cda1 100644 --- a/src/invidious/yt_backend/youtube_api.cr +++ b/src/invidious/yt_backend/youtube_api.cr @@ -135,6 +135,15 @@ module YoutubeAPI proxy_region: @proxy_region, }.to_s end + + # Converts to hash for displaying on error pages + def to_h + return { + client_type: self.name, + region: @region, + proxy_region: @proxy_region, + } + end end # Default client config, used if nothing is passed @@ -435,7 +444,17 @@ module YoutubeAPI end # Convert result to Hash - initial_data = JSON.parse(response.body).as_h + begin + initial_data = JSON.parse(response.body).as_h + rescue ex + raise InitialInnerTubeParseException.new(ex, + endpoint: endpoint.to_s, + client_config: client_config.to_h.to_pretty_json, + data: data.to_pretty_json, + status_code: response.status_code, + mime_type: "#{response.mime_type.try &.media_type}" + ) + end # Error handling if initial_data.has_key?("error")