Introduce more error types
This commit is contained in:

committed by
Sebastian Serth

parent
db2d1e3164
commit
cc412b73bc
@ -16,6 +16,12 @@ class Runner
|
|||||||
|
|
||||||
class RunnerNotFound < Error; end
|
class RunnerNotFound < Error; end
|
||||||
|
|
||||||
|
class FaradayError < Error; end
|
||||||
|
|
||||||
|
class UnexpectedResponse < Error; end
|
||||||
|
|
||||||
|
class WorkspaceError < Error; end
|
||||||
|
|
||||||
class Unknown < Error; end
|
class Unknown < Error; end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,9 +12,9 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
container_id = JSON.parse(Faraday.get("#{config[:pool][:location]}/docker_container_pool/get_container/#{environment.id}").body)['id']
|
container_id = JSON.parse(Faraday.get("#{config[:pool][:location]}/docker_container_pool/get_container/#{environment.id}").body)['id']
|
||||||
container_id.presence || raise(Runner::Error::NotAvailable.new("DockerContainerPool didn't return a container id"))
|
container_id.presence || raise(Runner::Error::NotAvailable.new("DockerContainerPool didn't return a container id"))
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to DockerContainerPool failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to DockerContainerPool failed: #{e.inspect}")
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
raise Runner::Error::Unknown.new("DockerContainerPool returned invalid JSON: #{e.inspect}")
|
raise Runner::Error::UnexpectedResponse.new("DockerContainerPool returned invalid JSON: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(runner_id, _environment)
|
def initialize(runner_id, _environment)
|
||||||
@ -40,7 +40,7 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
rescue IOError => e
|
rescue IOError => e
|
||||||
# TODO: try catch i/o exception and log failed attempts
|
# TODO: try catch i/o exception and log failed attempts
|
||||||
# Does this fix the issue @Sebastian? What exceptions did you have in mind?
|
# Does this fix the issue @Sebastian? What exceptions did you have in mind?
|
||||||
raise Runner::Error::Unknown.new("Could not create workspace file #{file.filepath}: #{e.inspect}")
|
raise Runner::Error::WorkspaceError.new("Could not create file #{file.filepath}: #{e.inspect}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -50,7 +50,7 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
def destroy_at_management
|
def destroy_at_management
|
||||||
Faraday.get("#{self.class.config[:pool][:location]}/docker_container_pool/destroy_container/#{container.id}")
|
Faraday.get("#{self.class.config[:pool][:location]}/docker_container_pool/destroy_container/#{container.id}")
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to DockerContainerPool failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to DockerContainerPool failed: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def attach_to_execution(command)
|
def attach_to_execution(command)
|
||||||
@ -88,7 +88,7 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
unclean_path = local_workspace_path.join(path)
|
unclean_path = local_workspace_path.join(path)
|
||||||
clean_path = File.expand_path(unclean_path)
|
clean_path = File.expand_path(unclean_path)
|
||||||
unless clean_path.to_s.start_with? local_workspace_path.to_s
|
unless clean_path.to_s.start_with? local_workspace_path.to_s
|
||||||
raise Runner::Error::Unknown.new("Local filepath #{clean_path.inspect} not allowed")
|
raise Runner::Error::WorkspaceError.new("Local filepath #{clean_path.inspect} not allowed")
|
||||||
end
|
end
|
||||||
|
|
||||||
Pathname.new(clean_path)
|
Pathname.new(clean_path)
|
||||||
@ -97,10 +97,10 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
def clean_workspace
|
def clean_workspace
|
||||||
FileUtils.rm_r(local_workspace_path.children, secure: true)
|
FileUtils.rm_r(local_workspace_path.children, secure: true)
|
||||||
rescue Errno::ENOENT => e
|
rescue Errno::ENOENT => e
|
||||||
raise Runner::Error::Unknown.new("The workspace directory does not exist and cannot be deleted: #{e.inspect}")
|
raise Runner::Error::WorkspaceError.new("The workspace directory does not exist and cannot be deleted: #{e.inspect}")
|
||||||
rescue Errno::EACCES => e
|
rescue Errno::EACCES => e
|
||||||
# TODO: Why was this rescued before @Sebastian?
|
# TODO: Why was this rescued before @Sebastian?
|
||||||
raise Runner::Error::Unknown.new("Not allowed to clean workspace #{local_workspace_path}: #{e.inspect}")
|
raise Runner::Error::WorkspaceError.new("Not allowed to clean workspace #{local_workspace_path}: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_workspace_path
|
def local_workspace_path
|
||||||
|
@ -23,14 +23,14 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
when 200
|
when 200
|
||||||
response_body = parse response
|
response_body = parse response
|
||||||
runner_id = response_body[:runnerId]
|
runner_id = response_body[:runnerId]
|
||||||
runner_id.presence || raise(Runner::Error::Unknown.new('Poseidon did not send a runner id'))
|
runner_id.presence || raise(Runner::Error::UnexpectedResponse.new('Poseidon did not send a runner id'))
|
||||||
when 404
|
when 404
|
||||||
raise Runner::Error::EnvironmentNotFound.new
|
raise Runner::Error::EnvironmentNotFound.new
|
||||||
else
|
else
|
||||||
handle_error response
|
handle_error response
|
||||||
end
|
end
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to runner management failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.handle_error(response)
|
def self.handle_error(response)
|
||||||
@ -51,7 +51,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
raise Runner::Error::InternalServerError.new("Poseidon sent #{response_body[:errorCode]}: #{response_body[:message]}")
|
raise Runner::Error::InternalServerError.new("Poseidon sent #{response_body[:errorCode]}: #{response_body[:message]}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise Runner::Error::Unknown.new("Poseidon sent unexpected response status code #{response.status}")
|
raise Runner::Error::UnexpectedResponse.new("Poseidon sent unexpected response status code #{response.status}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
JSON.parse(response.body).deep_symbolize_keys
|
JSON.parse(response.body).deep_symbolize_keys
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
# Poseidon should not send invalid json
|
# Poseidon should not send invalid json
|
||||||
raise Runner::Error::Unknown.new("Error parsing response from Poseidon: #{e.message}")
|
raise Runner::Error::UnexpectedResponse.new("Error parsing response from Poseidon: #{e.message}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(runner_id, _environment)
|
def initialize(runner_id, _environment)
|
||||||
@ -82,7 +82,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
Runner.destroy(@allocation_id) if response.status == 400
|
Runner.destroy(@allocation_id) if response.status == 400
|
||||||
self.class.handle_error response
|
self.class.handle_error response
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to runner management failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def attach_to_execution(command)
|
def attach_to_execution(command)
|
||||||
@ -99,7 +99,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
response = Faraday.delete runner_url
|
response = Faraday.delete runner_url
|
||||||
self.class.handle_error response unless response.status == 204
|
self.class.handle_error response unless response.status == 204
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to runner management failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -115,7 +115,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
if websocket_url.present?
|
if websocket_url.present?
|
||||||
return websocket_url
|
return websocket_url
|
||||||
else
|
else
|
||||||
raise Runner::Error::Unknown.new('Poseidon did not send websocket url')
|
raise Runner::Error::UnexpectedResponse.new('Poseidon did not send websocket url')
|
||||||
end
|
end
|
||||||
when 400
|
when 400
|
||||||
Runner.destroy(@allocation_id)
|
Runner.destroy(@allocation_id)
|
||||||
@ -123,7 +123,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
|
|
||||||
self.class.handle_error response
|
self.class.handle_error response
|
||||||
rescue Faraday::Error => e
|
rescue Faraday::Error => e
|
||||||
raise Runner::Error::Unknown.new("Faraday request to runner management failed: #{e.inspect}")
|
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def runner_url
|
def runner_url
|
||||||
@ -134,7 +134,7 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
def decode(raw_event)
|
def decode(raw_event)
|
||||||
JSON.parse(raw_event.data)
|
JSON.parse(raw_event.data)
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
raise Runner::Error::Unknown.new("The websocket message from Poseidon could not be decoded to JSON: #{e.inspect}")
|
raise Runner::Error::UnexpectedResponse.new("The websocket message from Poseidon could not be decoded to JSON: #{e.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def encode(data)
|
def encode(data)
|
||||||
|
@ -20,7 +20,7 @@ describe Runner::Strategy::DockerContainerPool do
|
|||||||
shared_examples 'Faraday error handling' do
|
shared_examples 'Faraday error handling' do
|
||||||
it 'raises a runner error' do
|
it 'raises a runner error' do
|
||||||
allow(Faraday).to receive(:get).and_raise(Faraday::TimeoutError)
|
allow(Faraday).to receive(:get).and_raise(Faraday::TimeoutError)
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown, /Faraday/)
|
expect { action.call }.to raise_error(Runner::Error::FaradayError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ describe Runner::Strategy::DockerContainerPool do
|
|||||||
let(:response_body) { '{hello}' }
|
let(:response_body) { '{hello}' }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ describe Runner::Strategy::DockerContainerPool do
|
|||||||
|
|
||||||
it 'raises an error in case of an IOError' do
|
it 'raises an error in case of an IOError' do
|
||||||
allow(File).to receive(:open).and_raise(IOError)
|
allow(File).to receive(:open).and_raise(IOError)
|
||||||
expect { container_pool.copy_files(files) }.to raise_error(Runner::Error::Unknown, /#{files.first.filepath}/)
|
expect { container_pool.copy_files(files) }.to raise_error(Runner::Error::WorkspaceError, /#{files.first.filepath}/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create a directory for it' do
|
it 'does not create a directory for it' do
|
||||||
@ -195,11 +195,11 @@ describe Runner::Strategy::DockerContainerPool do
|
|||||||
before { allow(container_pool).to receive(:local_workspace_path).and_return(local_workspace) }
|
before { allow(container_pool).to receive(:local_workspace_path).and_return(local_workspace) }
|
||||||
|
|
||||||
it 'raises an error for relative paths outside of the workspace' do
|
it 'raises an error for relative paths outside of the workspace' do
|
||||||
expect { container_pool.send(:local_path, '../exercise.py') }.to raise_error(Runner::Error::Unknown, %r{tmp/exercise.py})
|
expect { container_pool.send(:local_path, '../exercise.py') }.to raise_error(Runner::Error::WorkspaceError, %r{tmp/exercise.py})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an error for absolute paths outside of the workspace' do
|
it 'raises an error for absolute paths outside of the workspace' do
|
||||||
expect { container_pool.send(:local_path, '/test') }.to raise_error(Runner::Error::Unknown, %r{/test})
|
expect { container_pool.send(:local_path, '/test') }.to raise_error(Runner::Error::WorkspaceError, %r{/test})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'removes .. from the path' do
|
it 'removes .. from the path' do
|
||||||
@ -225,13 +225,13 @@ describe Runner::Strategy::DockerContainerPool do
|
|||||||
|
|
||||||
it 'raises an error if the workspace does not exist' do
|
it 'raises an error if the workspace does not exist' do
|
||||||
allow(local_workspace).to receive(:children).and_raise(Errno::ENOENT)
|
allow(local_workspace).to receive(:children).and_raise(Errno::ENOENT)
|
||||||
expect { container_pool.send(:clean_workspace) }.to raise_error(Runner::Error::Unknown, /not exist/)
|
expect { container_pool.send(:clean_workspace) }.to raise_error(Runner::Error::WorkspaceError, /not exist/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an error if it lacks permission for deleting an entry' do
|
it 'raises an error if it lacks permission for deleting an entry' do
|
||||||
allow(local_workspace).to receive(:children).and_return(['test.py'])
|
allow(local_workspace).to receive(:children).and_return(['test.py'])
|
||||||
allow(FileUtils).to receive(:remove_entry_secure).and_raise(Errno::EACCES)
|
allow(FileUtils).to receive(:remove_entry_secure).and_raise(Errno::EACCES)
|
||||||
expect { container_pool.send(:clean_workspace) }.to raise_error(Runner::Error::Unknown, /Not allowed/)
|
expect { container_pool.send(:clean_workspace) }.to raise_error(Runner::Error::WorkspaceError, /Not allowed/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
let(:response_status) { 1337 }
|
let(:response_status) { 1337 }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown, /#{response_status}/)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse, /#{response_status}/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -109,7 +109,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
%i[post patch delete].each {|message| allow(Faraday).to receive(message).and_raise(Faraday::TimeoutError) }
|
%i[post patch delete].each {|message| allow(Faraday).to receive(message).and_raise(Faraday::TimeoutError) }
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown, /Faraday/)
|
expect { action.call }.to raise_error(Runner::Error::FaradayError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -146,7 +146,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
let(:response_status) { 200 }
|
let(:response_status) { 200 }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
let(:response_status) { 200 }
|
let(:response_status) { 200 }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
let(:response_status) { 200 }
|
let(:response_status) { 200 }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ describe Runner::Strategy::Poseidon do
|
|||||||
let(:response_status) { 200 }
|
let(:response_status) { 200 }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect { action.call }.to raise_error(Runner::Error::Unknown)
|
expect { action.call }.to raise_error(Runner::Error::UnexpectedResponse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user