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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
require 'open4'
# add additional fields to Exception class to format errors according to OT-API
class RuntimeError
attr_accessor :http_code, :uri
def initialize message, uri=nil
super message
@uri = uri
@http_code ||= 500
$logger.error "\n"+self.to_turtle
end
# define to_ and self.from_ methods for various rdf formats
RDF_FORMATS.each do |format|
send :define_method, "to_#{format}".to_sym do
rdf = RDF::Writer.for(format).buffer do |writer|
# TODO: not used for turtle
# http://rdf.rubyforge.org/RDF/Writer.html#
writer.prefix :ot, RDF::URI('http://www.opentox.org/api/1.2#')
writer.prefix :ot1_1, RDF::URI('http://www.opentox.org/api/1.1#')
subject = RDF::Node.new
writer << [subject, RDF.type, RDF::OT.ErrorReport]
writer << [subject, RDF::OT.actor, @uri.to_s]
writer << [subject, RDF::OT.message, @message.to_s]
writer << [subject, RDF::OT.statusCode, @http_code]
writer << [subject, RDF::OT.errorCode, self.class.to_s]
# cut backtrace
backtrace = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact
cut_index = backtrace.find_index{|line| line.match /sinatra|minitest/}
cut_index ||= backtrace.size
cut_index -= 1
cut_index = backtrace.size-1 if cut_index < 0
details = backtrace[0..cut_index].join("\n")
details += "REST paramenters:\n#{@request.args.inspect}" if @request
writer << [subject, RDF::OT.errorCause, details]
end
rdf
end
end
end
module OpenTox
class Error < RuntimeError
def initialize code, message, uri=nil
@http_code = code
super message, uri
end
end
# OpenTox errors
{
"BadRequestError" => 400,
"NotAuthorizedError" => 401,
"NotFoundError" => 404,
"LockedError" => 423,
"InternalServerError" => 500,
"NotImplementedError" => 501,
"ServiceUnavailableError" => 503,
"TimeOutError" => 504,
}.each do |klass,code|
# create error classes
c = Class.new Error do
define_method :initialize do |message, uri=nil|
super code, message, uri
end
end
OpenTox.const_set klass,c
# define global methods for raising errors, eg. bad_request_error
Object.send(:define_method, klass.underscore.to_sym) do |message,uri=nil|
raise c, message, uri
end
end
# Errors received from RestClientWrapper calls
class RestCallError < Error
attr_accessor :request#, :response
def initialize message, request, uri
#def initialize request, response, message
@request = request
#@response = response
super 502, message, uri
end
end
=begin
# TODO: create reports directly from errors, requires modified task service
class ErrorReport
def initialize http_code, error
@http_code = http_code
@report = {}
@report[RDF::OT.actor] = error.uri.to_s
@report[RDF::OT.message] = error.message.to_s
@report[RDF::OT.statusCode] = @http_code
@report[RDF::OT.errorCode] = error.class.to_s
# cut backtrace
backtrace = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact
cut_index = backtrace.find_index{|line| line.match /sinatra|minitest/}
cut_index ||= backtrace.size
cut_index -= 1
cut_index = backtrace.size-1 if cut_index < 0
@report[RDF::OT.errorDetails] = backtrace[0..cut_index].join("\n")
@report[RDF::OT.errorDetails] += "REST paramenters:\n#{error.request.args.inspect}" if defined? error.request
#@report[RDF::OT.message] += "\n" + error.response.body.to_s if defined? error.response
# TODO fix Error cause
# should point to another errorReport, but errorReports do not have URIs
# create a separate service?
#report[RDF::OT.errorCause] = @report if defined?(@report)
end
# define to_ and self.from_ methods for various rdf formats
RDF_FORMATS.each do |format|
send :define_method, "to_#{format}".to_sym do
rdf = RDF::Writer.for(format).buffer do |writer|
# TODO: not used for turtle
# http://rdf.rubyforge.org/RDF/Writer.html#
writer.prefix :ot, RDF::URI('http://www.opentox.org/api/1.2#')
writer.prefix :ot1_1, RDF::URI('http://www.opentox.org/api/1.1#')
subject = RDF::Node.new
@report.each do |predicate,object|
writer << [subject, predicate, object] if object
end
end
rdf
end
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
end
end
=end
end
|