summaryrefslogtreecommitdiff
path: root/lib/error.rb
blob: 7fc246102da6f4e0c97d77cd97617460518bb0d3 (plain)
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
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.report.to_turtle
  end

  def report
    # TODO: remove kludge for old task services
    OpenTox::ErrorReport.new(@http_code, self)
  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|
      defined?(@uri) ? uri = @uri : uri=nil
      # TODO: insert uri from sinatra
      raise c, message, uri
    end
  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, request.url
    end
  end

  # TODO: create reports directly from errors, requires modified task service
  class ErrorReport
    def initialize http_code, error
      @http_code = http_code
      #@report = report#.to_yaml
      @report = {}
      @report[RDF::OT.actor] = error.uri
      @report[RDF::OT.message] = error.message
      @report[RDF::OT.statusCode] = @http_code 
      @report[RDF::OT.errorCode] = error.class.to_s
      @report[RDF::OT.errorDetails] = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact.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 if defined? error.response
      # TODO fix Error cause
      #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|
          subject = RDF::Node.new
          @report.each do |predicate,object|
            writer << [subject, predicate, object] if object
          end
        end
        rdf
      end

=begin
      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