1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# adding additional fields to Exception class to format errors according to OT-API
class RuntimeError
attr_accessor :report, :http_code
def initialize message
super message
@http_code ||= 500
@report = OpenTox::ErrorReport.create self
$logger.error "\n"+@report.to_ntriples
end
end
module OpenTox
class Error < RuntimeError
def initialize code, message
@http_code = code
super message
end
end
# create error classes dynamically
{
"BadRequestError" => 400,
"NotAuthorizedError" => 401,
"NotFoundError" => 404,
"ServiceUnavailableError" => 503,
"TimeOutError" => 504,
}.each do |klass,code|
c = Class.new Error do
define_method :initialize do |message|
super code, message
end
end
OpenTox.const_set klass,c
end
# Errors received from RestClientWrapper calls
class RestCallError < Error
attr_accessor :request, :response
def initialize request, response, message
@request = request
@response = response
super 502, message
end
end
class ErrorReport
attr_accessor :rdf # RDF Graph
attr_accessor :http_code # TODO: remove when task service is fixed
def initialize
@rdf = RDF::Graph.new
end
# creates a error report object, from an ruby-exception object
# @param [Exception] error
def self.create error
report = ErrorReport.new
subject = RDF::Node.new
report.rdf << [subject, RDF.type, RDF::OT.ErrorReport]
message = error.message
errorDetails = ""
if error.respond_to? :request
report.rdf << [subject, RDF::OT.actor, error.request.url ]
errorDetails += "REST paramenters:\n#{error.request.args.inspect}"
end
error.respond_to?(:http_code) ? statusCode = error.http_code : statusCode = 500
if error.respond_to? :response
statusCode = error.response.code
message = error.body
end
statusCode = error.http_code if error.respond_to? :http_code
report.rdf << [subject, RDF::OT.statusCode, statusCode ]
report.rdf << [subject, RDF::OT.errorCode, error.class.to_s ]
# TODO: remove kludge for old task services
report.http_code = statusCode
report.rdf << [subject, RDF::OT.message , message ]
errorDetails += "\nBacktrace:\n" + error.backtrace.short_backtrace if error.respond_to?(:backtrace) and error.backtrace
report.rdf << [subject, RDF::OT.errorDetails, errorDetails ]
# TODO Error cause
#report.rdf << [subject, OT.errorCause, error.report] if error.respond_to?(:report) and !error.report.empty?
report
end
# define to_ and self.from_ methods for various rdf formats
[:rdfxml,:ntriples].each do |format|
define_singleton_method ("from_#{format}").to_sym do |rdf|
report = ErrorReport.new
RDF::Reader.for(format).new(rdf) do |reader|
reader.each_statement{ |statement| report.rdf << statement }
end
report
end
send :define_method, ("to_#{format}").to_sym do
rdfxml = RDF::Writer.for(format).buffer do |writer|
@rdf.each{|statement| writer << statement}
end
rdfxml
end
end
end
end
class Array
def short_backtrace
short = []
each do |c|
break if c =~ /sinatra\/base/
short << c
end
short.join("\n")
end
end
|