diff --git a/lib/puppet/configurer/fact_handler.rb b/lib/puppet/configurer/fact_handler.rb index 64f8fb9da9..1cf01fb69f 100644 --- a/lib/puppet/configurer/fact_handler.rb +++ b/lib/puppet/configurer/fact_handler.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require_relative '../../puppet/agent' require_relative '../../puppet/indirector/facts/facter' require_relative '../../puppet/configurer' @@ -20,7 +21,10 @@ def find_facts facts.name = Puppet[:node_name_value] end facts - rescue SystemExit, NoMemoryError + rescue SystemExit, NoMemoryError, Puppet::Agent::RunTimeoutError + # RunTimeoutError means the agent run as a whole has exceeded `runtimeout`. + # Let it propagate so the run is aborted instead of wrapping it in a + # Puppet::Error and carrying on with the rest of the run. raise rescue Exception => detail message = _("Could not retrieve local facts: %{detail}") % { detail: detail } diff --git a/spec/unit/configurer/fact_handler_spec.rb b/spec/unit/configurer/fact_handler_spec.rb index 1acf49c30a..16dc932b8b 100644 --- a/spec/unit/configurer/fact_handler_spec.rb +++ b/spec/unit/configurer/fact_handler_spec.rb @@ -58,6 +58,13 @@ def reload_facter expect { facthandler.find_facts }.to raise_error(Puppet::Error, /Could not retrieve local facts/) end + it "should re-raise RunTimeoutError so the agent run is aborted" do + expect(Puppet::Node::Facts.indirection).to receive(:find).and_raise(Puppet::Agent::RunTimeoutError, 'execution expired') + expect(Puppet).not_to receive(:log_exception) + + expect { facthandler.find_facts }.to raise_error(Puppet::Agent::RunTimeoutError, 'execution expired') + end + it "should only load fact plugins once" do expect(Puppet::Node::Facts.indirection).to receive(:find).once facthandler.find_facts