From 87be6fe98c184bac0c9a50a988bff4be618da059 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Sun, 6 Oct 2019 20:47:33 +0200 Subject: [PATCH] DEV: Add a plugin incompatibility message (#8151) * DEV: Add a plugin incompatibility message * Extract the plugin_initialization_guard --- config/application.rb | 9 +++++-- lib/plugin_initialization_guard.rb | 38 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 lib/plugin_initialization_guard.rb diff --git a/config/application.rb b/config/application.rb index b0938cb2baf..dd56bf859fe 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,6 +21,7 @@ require 'action_mailer/railtie' require 'sprockets/railtie' # Plugin related stuff +require_relative '../lib/plugin_initialization_guard' require_relative '../lib/discourse_event' require_relative '../lib/discourse_plugin' require_relative '../lib/discourse_plugin_registry' @@ -266,7 +267,9 @@ module Discourse Discourse.activate_plugins! end else - Discourse.activate_plugins! + plugin_initialization_guard do + Discourse.activate_plugins! + end end Discourse.find_plugin_js_assets(include_disabled: true).each do |file| @@ -301,7 +304,9 @@ module Discourse OpenID::Util.logger = Rails.logger # Load plugins - Discourse.plugins.each(&:notify_after_initialize) + plugin_initialization_guard do + Discourse.plugins.each(&:notify_after_initialize) + end # we got to clear the pool in case plugins connect ActiveRecord::Base.connection_handler.clear_active_connections! diff --git a/lib/plugin_initialization_guard.rb b/lib/plugin_initialization_guard.rb new file mode 100644 index 00000000000..a5a164e9e2e --- /dev/null +++ b/lib/plugin_initialization_guard.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +def plugin_initialization_guard(&block) + begin + block.call + rescue => error + plugins_directory = Rails.root + 'plugins' + + plugin_path = error.backtrace_locations.lazy.map do |location| + Pathname.new(location.absolute_path) + .ascend + .lazy + .find { |path| path.parent == plugins_directory } + end.next + + raise unless plugin_path + + stack_trace = error.backtrace.each_with_index.inject([]) do |messages, (line, index)| + if index == 0 + messages << "#{line}: #{error} (#{error.class})" + else + messages << "\t#{index}: from #{line}" + end + end.reverse.join("\n") + + STDERR.puts <<~MESSAGE + #{stack_trace} + + ** INCOMPATIBLE PLUGIN ** + + You are unable to build Discourse due to errors in the plugin at + #{plugin_path} + + Please try removing this plugin and rebuilding again! + MESSAGE + exit 1 + end +end