Gracefully handle errors in parallel cases
This commit is contained in:
parent
368dddd950
commit
c84c609633
|
@ -53,15 +53,61 @@ module Vagrant
|
|||
@actions.each do |machine, action, options|
|
||||
@logger.info("Starting action: #{machine} #{action} #{options}")
|
||||
|
||||
thread = Thread.new { machine.send(:action, action, options) }
|
||||
# Create the new thread to run our action. This is basically just
|
||||
# calling the action but also contains some error handling in it
|
||||
# as well.
|
||||
thread = Thread.new do
|
||||
Thread.current[:error] = nil
|
||||
|
||||
begin
|
||||
machine.send(:action, action, options)
|
||||
rescue Exception => e
|
||||
# If we're not parallelizing, then raise the error
|
||||
raise if !par
|
||||
|
||||
# Store the exception that will be processed later
|
||||
Thread.current[:error] = e
|
||||
end
|
||||
end
|
||||
|
||||
# Set some attributes on the thread for later
|
||||
thread[:machine] = machine
|
||||
|
||||
thread.join if !par
|
||||
threads << thread
|
||||
end
|
||||
|
||||
# Join the threads, which will return immediately if parallelization
|
||||
# if disabled, because we already joined on them. Otherwise, this
|
||||
# will wait for completion of all threads.
|
||||
threads.map(&:join)
|
||||
errors = []
|
||||
|
||||
threads.each do |thread|
|
||||
# Wait for the thread to complete
|
||||
thread.join
|
||||
|
||||
# If the thread had an error, then store the error to show later
|
||||
if thread[:error]
|
||||
e = thread[:error]
|
||||
# If the error isn't a Vagrant error, then store the backtrace
|
||||
# as well.
|
||||
if !thread[:error].is_a?(Errors::VagrantError)
|
||||
e = thread[:error]
|
||||
message = e.message
|
||||
message += "\n"
|
||||
message += "\n#{e.backtrace.join("\n")}"
|
||||
|
||||
errors << I18n.t("vagrant.general.batch_unexpected_error",
|
||||
:machine => thread[:machine].name,
|
||||
:message => message)
|
||||
else
|
||||
errors << I18n.t("vagrant.general.batch_vagrant_error",
|
||||
:machine => thread[:machine].name,
|
||||
:message => thread[:error].message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !errors.empty?
|
||||
raise Errors::BatchMultiError, :message => errors.join("\n\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -91,6 +91,10 @@ module Vagrant
|
|||
error_key(:base_vm_not_found)
|
||||
end
|
||||
|
||||
class BatchMultiError < VagrantError
|
||||
error_key(:batch_multi_error)
|
||||
end
|
||||
|
||||
class BoxAlreadyExists < VagrantError
|
||||
error_key(:already_exists, "vagrant.actions.box.unpackage")
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module VagrantPlugins
|
|||
VirtualBox-based virtual machines.
|
||||
EOF
|
||||
|
||||
provider(:virtualbox) do
|
||||
provider(:virtualbox, parallel: true) do
|
||||
require File.expand_path("../provider", __FILE__)
|
||||
Provider
|
||||
end
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
en:
|
||||
vagrant:
|
||||
general:
|
||||
batch_unexpected_error: |-
|
||||
An unexpected error ocurred when executing the action on the
|
||||
'%{machine}' machine. Please report this as a bug:
|
||||
|
||||
%{message}
|
||||
batch_vagrant_error: |-
|
||||
An error occurred while executing the action on the '%{machine}'
|
||||
machine. Please handle this error then try again:
|
||||
|
||||
%{message}
|
||||
config_upgrade_messages: |-
|
||||
There were warnings and/or errors while loading your Vagrantfile.
|
||||
Your Vagrantfile was written for an earlier version of Vagrant,
|
||||
|
@ -57,6 +67,11 @@ en:
|
|||
Active provider: %{active_provider}
|
||||
Requested provider: %{requested_provider}
|
||||
base_vm_not_found: The base VM with the name '%{name}' was not found.
|
||||
batch_multi_error: |-
|
||||
An error occurred while executing multiple actions in parallel.
|
||||
Any errors that occurred are shown below.
|
||||
|
||||
%{message}
|
||||
box_metadata_file_not_found: |-
|
||||
The "metadata.json" file for the box '%{name}' was not found.
|
||||
Boxes require this file in order for Vagrant to determine the
|
||||
|
|
Loading…
Reference in New Issue