From c2986f418ede0ea443df0a1f7690c433b637dc57 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Wed, 29 Feb 2012 18:50:41 +0000 Subject: TaskError implemented, logging still partially redundant --- lib/error.rb | 72 +++++++++++++++++-------------------- lib/otlogger.rb | 2 +- lib/rest-client-wrapper.rb | 88 ++++++++++++++++++++++++++++++++-------------- lib/task.rb | 10 +++--- test/task.rb | 6 +++- 5 files changed, 104 insertions(+), 74 deletions(-) diff --git a/lib/error.rb b/lib/error.rb index b832ef4..0e467d9 100644 --- a/lib/error.rb +++ b/lib/error.rb @@ -1,47 +1,38 @@ # adding additional fields to Exception class to format errors according to OT-API -=begin -class Exception -end -=end class RuntimeError - attr_accessor :errorCause # is errorReport - def initialize msg=nil - $logger.error msg - super msg - end - def http_code; 500; end + attr_accessor :http_code + @http_code = 500 end module OpenTox - - class BadRequestError < RuntimeError - def http_code; 400; end - end - - class NotAuthorizedError < RuntimeError - def http_code; 401; end - end - - class NotFoundError < RuntimeError - def http_code; 404; end - end - - class LockedError < RuntimeError - def http_code; 423; end - end - class ServiceUnavailableError < RuntimeError - def http_code; 503; end + # Errors received from RestClientWrapper calls + class RestError < RuntimeError + attr_accessor :request, :response, :cause + def initialize args + @request = args[:request] + @response = args[:response] + args[:http_code] ? @http_code = args[:http_code] : @http_code = @response.code if @response + @cause = args[:cause] + msg = args.to_yaml + $logger.error msg + super msg + end end - - class RestCallError < RuntimeError - def initialize request, response, expectation=nil - msg = "REST request: #{request.inspect}\nREST response: #{response.inspect}" - msg += "\n"+expectation if expectation + + # Errors rescued from task blocks + class TaskError < RuntimeError + attr_reader :error, :actor, :report + def initialize error, actor=nil + @error = error + @actor = actor + @report = ErrorReport.create error, actor + msg = "\nActor: \"#{actor}\"\n" + msg += @error.to_yaml + #$logger.error msg super msg end - def http_code; 502; end end class ErrorReport @@ -52,7 +43,7 @@ module OpenTox private def initialize( http_code, erroType, message, actor, errorCause, rest_params=nil, backtrace=nil ) @http_code = http_code - @errorType = erroType + #@errorType = erroType @message = message @actor = actor @errorCause = errorCause @@ -65,9 +56,11 @@ module OpenTox # @param [Exception] error # @param [String] actor, URI of the call that cause the error def self.create( error, actor ) - rest_params = error.rest_params if error.is_a?(OpenTox::RestCallError) and error.rest_params - backtrace = error.backtrace.short_backtrace #if CONFIG[:backtrace] - ErrorReport.new( error.http_code, error.class.to_s, error.message, actor, error.errorCause, rest_params, backtrace ) + rest_params = error.request if error.respond_to? :request + backtrace = error.backtrace.short_backtrace if error.respond_to? :backtrace and error.backtrace #if CONFIG[:backtrace] + error.respond_to?(:http_code) ? http_code = error.http_code : http_code = 500 + error.respond_to?(:cause) ? cause = error.cause : cause = 'Unknown' + ErrorReport.new( http_code, error.class.to_s, error.message, actor, cause, rest_params, backtrace ) end def self.from_rdf(rdf) @@ -101,8 +94,7 @@ module OpenTox s.add_resource(CONFIG[:services]["opentox-task"]+"/tmpId/ErrorReport/tmpId", OT.errorReport, rdf_content) s.to_rdfxml end -=begin -=end + end end diff --git a/lib/otlogger.rb b/lib/otlogger.rb index e9fbc4d..57b8170 100644 --- a/lib/otlogger.rb +++ b/lib/otlogger.rb @@ -12,7 +12,7 @@ class OTLogger < Logger n = 2 line = lines[n] - while (line =~ /spork.rb/ or line =~ /create/ or line =~ /#{File.basename(__FILE__)}/) + while (line =~ /error.rb/ or line =~ /create/ or line =~ /#{File.basename(__FILE__)}/) n += 1 line = lines[n] end diff --git a/lib/rest-client-wrapper.rb b/lib/rest-client-wrapper.rb index 67114fb..1e871b0 100644 --- a/lib/rest-client-wrapper.rb +++ b/lib/rest-client-wrapper.rb @@ -17,15 +17,7 @@ module OpenTox define_singleton_method method do |uri,payload={},headers={},waiting_task=nil, wait=true| - # catch input errors - raise OpenTox::BadRequestError.new "Invalid URI: '#{uri}'" unless URI.valid? uri - raise OpenTox::BadRequestError.new "Unreachable URI: '#{uri}'" unless URI.accessible? uri - raise OpenTox::BadRequestError.new "Headers are not a hash: #{headers.inspect}" unless headers==nil or headers.is_a?(Hash) - [:accept,:content_type,:subjectid].each do |header| - raise OpenTox::BadRequestError.new "#{header} should be submitted in the headers" if payload and payload.is_a?(Hash) and payload[header] - end - raise OpenTox::BadRequestError "waiting_task is not 'nil', OpenTox::SubTask or OpenTox::Task: #{waiting_task.class}" unless waiting_task.nil? or waiting_task.is_a?(OpenTox::Task) or waiting_task.is_a?(OpenTox::SubTask) - + # create request args={} args[:method] = method args[:url] = uri @@ -33,13 +25,23 @@ module OpenTox args[:payload] = payload headers.each{ |k,v| headers.delete(k) if v==nil } if headers #remove keys with empty values, as this can cause problems args[:headers] = headers + @request = RestClient::Request.new(args) + + # catch input errors + rest_error "Invalid URI: '#{uri}'" unless URI.valid? uri + rest_error "Unreachable URI: '#{uri}'" unless URI.accessible? uri + rest_error "Headers are not a hash: #{headers.inspect}" unless headers==nil or headers.is_a?(Hash) + # make sure that no header parameters are set in payload + [:accept,:content_type,:subjectid].each do |header| + rest_error "#{header} should be submitted in the headers" if payload and payload.is_a?(Hash) and payload[header] + end + rest_error "waiting_task is not 'nil', OpenTox::SubTask or OpenTox::Task: #{waiting_task.class}" unless waiting_task.nil? or waiting_task.is_a?(OpenTox::Task) or waiting_task.is_a?(OpenTox::SubTask) begin - @request = RestClient::Request.new(args) @response = @request.execute do |response, request, result| # ignore error codes from Task services (may contain eg 500 which causes exceptions in RestClient and RDF::Reader - rest_call_error unless response.code < 400 or URI.task? uri + rest_error unless response.code < 400 or URI.task? uri return response end @@ -55,26 +57,34 @@ module OpenTox end return @response - rescue RestClient::RequestTimeout => ex - received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload} - rescue Errno::ETIMEDOUT => ex - received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload} - rescue Errno::ECONNREFUSED => ex - received_error ex.message, 500, nil, {:rest_uri => uri, :headers => headers, :payload => payload} - rescue RestClient::ExceptionWithResponse => ex + rescue + rest_error $!.message + end +=begin + rescue RestClient::RequestTimeout + raise OpenTox::Error @request, @response, $!.message + #received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload} + rescue Errno::ETIMEDOUT + raise OpenTox::Error @request, @response, $!.message + #received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload} + rescue Errno::ECONNREFUSED + raise OpenTox::Error $!.message + #received_error ex.message, 500, nil, {:rest_uri => uri, :headers => headers, :payload => payload} + rescue RestClient::ExceptionWithResponse # error comming from a different webservice, received_error ex.http_body, ex.http_code, ex.response.net_http_res.content_type, {:rest_uri => uri, :headers => headers, :payload => payload} - rescue OpenTox::RestCallError => ex + #rescue OpenTox::RestCallError => ex # already a rest-error, probably comes from wait_for_task, just pass through - raise ex - rescue => ex + #raise ex + #rescue => ex # some internal error occuring in rest-client-wrapper, just pass through - raise ex + #raise ex end +=end end end - def self.wait_for_task( response, base_uri, waiting_task=nil ) + def wait_for_task( response, base_uri, waiting_task=nil ) #TODO remove TUM hack # @response.headers[:content_type] = "text/uri-list" if base_uri =~/tu-muenchen/ and @response.headers[:content_type] == "application/x-www-form-urlencoded;charset=UTF-8" @@ -85,10 +95,10 @@ module OpenTox #task = OpenTox::Task.from_rdfxml(@response) #task = OpenTox::Task.from_rdfxml(@response) when /text\/uri-list/ - rest_call_error "Uri list has more than one entry, should be a single task" if @response.split("\n").size > 1 #if uri list contains more then one uri, its not a task + rest_error "Uri list has more than one entry, should be a single task" if @response.split("\n").size > 1 #if uri list contains more then one uri, its not a task task = OpenTox::Task.new(@response.to_s.chomp) if URI.available? @response.to_s else - rest_call_error @response, "Unknown content-type for task : '"+@response.headers[:content_type].to_s+"'"+" base-uri: "+base_uri.to_s+" content: "+@response[0..200].to_s + rest_error @response, "Unknown content-type for task : '"+@response.headers[:content_type].to_s+"'"+" base-uri: "+base_uri.to_s+" content: "+@response[0..200].to_s end #LOGGER.debug "result is a task '"+task.uri.to_s+"', wait for completion" @@ -104,14 +114,37 @@ module OpenTox @response end - def rest_call_error message - raise OpenTox::RestCallError @request, @response, message + def self.rest_error message + raise OpenTox::RestError.new :request => @request, :response => @response, :cause => message + end + +=begin + def self.bad_request_error message + raise OpenTox::Error.new message + end + + def self.not_found_error message + raise OpenTox::NotFoundError.new message end + def self.received_error( body, code, content_type=nil, params=nil ) + + # try to parse body TODO + body.is_a?(OpenTox::ErrorReport) ? report = body : report = OpenTox::ErrorReport.from_rdf(body) + rest_call_error "REST call returned error: '"+body.to_s+"'" unless report + # parsing sucessfull + # raise RestCallError with parsed report as error cause + err = OpenTox::RestCallError.new(@request, @response, "REST call subsequent error") + err.errorCause = report + raise err + end +=end +=begin def self.received_error( body, code, content_type=nil, params=nil ) # try to parse body report = nil + #report = OpenTox::ErrorReport.from_rdf(body) if body.is_a?(OpenTox::ErrorReport) report = body else @@ -138,5 +171,6 @@ module OpenTox raise err end end +=end end end diff --git a/lib/task.rb b/lib/task.rb index 635584f..a28a0aa 100644 --- a/lib/task.rb +++ b/lib/task.rb @@ -9,6 +9,7 @@ module OpenTox def self.create service_uri, params={} + # TODO set request uri task = Task.new RestClientWrapper.post(service_uri,params).chomp pid = fork do begin @@ -16,7 +17,7 @@ module OpenTox if URI.accessible?(result_uri) task.completed result_uri else - raise "#{result_uri} is not a valid URI" + task.error OpenTox::RestError.new :http_code => 404, :cause => "#{result_uri} is not a valid URI", :actor => params[:creator] end rescue task.error $! @@ -62,14 +63,13 @@ module OpenTox def completed(uri) #TODO: subjectid? #TODO: error code - raise "\"#{uri}\" does not exist." unless URI.accessible? uri + error OpenTox::RestError.new :http_code => 404, :cause => "\"#{uri}\" does not exist.", :actor => creator unless URI.accessible? uri RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri}) end def error error - $logger.error self - report = ErrorReport.create(error,self.creator) - RestClientWrapper.put(File.join(@uri,'Error'),{:errorReport => report}) + error = OpenTox::TaskError.new error, self.creator + RestClientWrapper.put(File.join(@uri,'Error'),{:errorReport => error.report}) kill raise error end diff --git a/test/task.rb b/test/task.rb index ea5ee2f..f01282b 100644 --- a/test/task.rb +++ b/test/task.rb @@ -10,6 +10,8 @@ TASK_SERVICE_URI = "http://ot-dev.in-silico.ch/task" class TaskTest < Test::Unit::TestCase +=begin +=end def test_all all = OpenTox::Task.all(TASK_SERVICE_URI) assert_equal Array, all.class @@ -45,7 +47,7 @@ class TaskTest < Test::Unit::TestCase def test_create_and_fail task = OpenTox::Task.create TASK_SERVICE_URI, :description => "test failure", :creator => "http://test.org/fake_creator" do sleep 1 - raise "an error occured" + raise "an unexpected error occured" end assert task.running? assert_equal "Running", task.hasStatus @@ -65,5 +67,7 @@ class TaskTest < Test::Unit::TestCase assert task.error? assert_equal "Error", task.hasStatus end +=begin +=end end -- cgit v1.2.3