File: exceptions.rb

package info (click to toggle)
ruby-rest-client 2.1.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 860 kB
  • sloc: ruby: 3,844; makefile: 5
file content (244 lines) | stat: -rw-r--r-- 7,982 bytes parent folder | download | duplicates (3)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
module RestClient

  # Hash of HTTP status code => message.
  #
  # 1xx: Informational - Request received, continuing process
  # 2xx: Success - The action was successfully received, understood, and
  #      accepted
  # 3xx: Redirection - Further action must be taken in order to complete the
  #      request
  # 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
  # 5xx: Server Error - The server failed to fulfill an apparently valid
  #      request
  #
  # @see
  #   http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
  #
  STATUSES = {100 => 'Continue',
              101 => 'Switching Protocols',
              102 => 'Processing', #WebDAV

              200 => 'OK',
              201 => 'Created',
              202 => 'Accepted',
              203 => 'Non-Authoritative Information', # http/1.1
              204 => 'No Content',
              205 => 'Reset Content',
              206 => 'Partial Content',
              207 => 'Multi-Status', #WebDAV
              208 => 'Already Reported', # RFC5842
              226 => 'IM Used', # RFC3229

              300 => 'Multiple Choices',
              301 => 'Moved Permanently',
              302 => 'Found',
              303 => 'See Other', # http/1.1
              304 => 'Not Modified',
              305 => 'Use Proxy', # http/1.1
              306 => 'Switch Proxy', # no longer used
              307 => 'Temporary Redirect', # http/1.1
              308 => 'Permanent Redirect', # RFC7538

              400 => 'Bad Request',
              401 => 'Unauthorized',
              402 => 'Payment Required',
              403 => 'Forbidden',
              404 => 'Not Found',
              405 => 'Method Not Allowed',
              406 => 'Not Acceptable',
              407 => 'Proxy Authentication Required',
              408 => 'Request Timeout',
              409 => 'Conflict',
              410 => 'Gone',
              411 => 'Length Required',
              412 => 'Precondition Failed',
              413 => 'Payload Too Large', # RFC7231 (renamed, see below)
              414 => 'URI Too Long', # RFC7231 (renamed, see below)
              415 => 'Unsupported Media Type',
              416 => 'Range Not Satisfiable', # RFC7233 (renamed, see below)
              417 => 'Expectation Failed',
              418 => 'I\'m A Teapot', #RFC2324
              421 => 'Too Many Connections From This IP',
              422 => 'Unprocessable Entity', #WebDAV
              423 => 'Locked', #WebDAV
              424 => 'Failed Dependency', #WebDAV
              425 => 'Unordered Collection', #WebDAV
              426 => 'Upgrade Required',
              428 => 'Precondition Required', #RFC6585
              429 => 'Too Many Requests', #RFC6585
              431 => 'Request Header Fields Too Large', #RFC6585
              449 => 'Retry With', #Microsoft
              450 => 'Blocked By Windows Parental Controls', #Microsoft

              500 => 'Internal Server Error',
              501 => 'Not Implemented',
              502 => 'Bad Gateway',
              503 => 'Service Unavailable',
              504 => 'Gateway Timeout',
              505 => 'HTTP Version Not Supported',
              506 => 'Variant Also Negotiates',
              507 => 'Insufficient Storage', #WebDAV
              508 => 'Loop Detected', # RFC5842
              509 => 'Bandwidth Limit Exceeded', #Apache
              510 => 'Not Extended',
              511 => 'Network Authentication Required', # RFC6585
  }

  STATUSES_COMPATIBILITY = {
    # The RFCs all specify "Not Found", but "Resource Not Found" was used in
    # earlier RestClient releases.
    404 => ['ResourceNotFound'],

    # HTTP 413 was renamed to "Payload Too Large" in RFC7231.
    413 => ['RequestEntityTooLarge'],

    # HTTP 414 was renamed to "URI Too Long" in RFC7231.
    414 => ['RequestURITooLong'],

    # HTTP 416 was renamed to "Range Not Satisfiable" in RFC7233.
    416 => ['RequestedRangeNotSatisfiable'],
  }


  # This is the base RestClient exception class. Rescue it if you want to
  # catch any exception that your request might raise
  # You can get the status code by e.http_code, or see anything about the
  # response via e.response.
  # For example, the entire result body (which is
  # probably an HTML error page) is e.response.
  class Exception < RuntimeError
    attr_accessor :response
    attr_accessor :original_exception
    attr_writer :message

    def initialize response = nil, initial_response_code = nil
      @response = response
      @message = nil
      @initial_response_code = initial_response_code
    end

    def http_code
      # return integer for compatibility
      if @response
        @response.code.to_i
      else
        @initial_response_code
      end
    end

    def http_headers
      @response.headers if @response
    end

    def http_body
      @response.body if @response
    end

    def to_s
      message
    end

    def message
      @message || default_message
    end

    def default_message
      self.class.name
    end
  end

  # Compatibility
  class ExceptionWithResponse < RestClient::Exception
  end

  # The request failed with an error code not managed by the code
  class RequestFailed < ExceptionWithResponse

    def default_message
      "HTTP status code #{http_code}"
    end

    def to_s
      message
    end
  end

  # RestClient exception classes. TODO: move all exceptions into this module.
  #
  # We will a create an exception for each status code, see
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
  #
  module Exceptions
    # Map http status codes to the corresponding exception class
    EXCEPTIONS_MAP = {}
  end

  # Create HTTP status exception classes
  STATUSES.each_pair do |code, message|
    klass = Class.new(RequestFailed) do
      send(:define_method, :default_message) {"#{http_code ? "#{http_code} " : ''}#{message}"}
    end
    klass_constant = const_set(message.delete(' \-\''), klass)
    Exceptions::EXCEPTIONS_MAP[code] = klass_constant
  end

  # Create HTTP status exception classes used for backwards compatibility
  STATUSES_COMPATIBILITY.each_pair do |code, compat_list|
    klass = Exceptions::EXCEPTIONS_MAP.fetch(code)
    compat_list.each do |old_name|
      const_set(old_name, klass)
    end
  end

  module Exceptions
    # We have to split the Exceptions module like we do here because the
    # EXCEPTIONS_MAP is under Exceptions, but we depend on
    # RestClient::RequestTimeout below.

    # Base class for request timeouts.
    #
    # NB: Previous releases of rest-client would raise RequestTimeout both for
    # HTTP 408 responses and for actual connection timeouts.
    class Timeout < RestClient::RequestTimeout
      def initialize(message=nil, original_exception=nil)
        super(nil, nil)
        self.message = message if message
        self.original_exception = original_exception if original_exception
      end
    end

    # Timeout when connecting to a server. Typically wraps Net::OpenTimeout (in
    # ruby 2.0 or greater).
    class OpenTimeout < Timeout
      def default_message
        'Timed out connecting to server'
      end
    end

    # Timeout when reading from a server. Typically wraps Net::ReadTimeout (in
    # ruby 2.0 or greater).
    class ReadTimeout < Timeout
      def default_message
        'Timed out reading data from server'
      end
    end
  end


  # The server broke the connection prior to the request completing.  Usually
  # this means it crashed, or sometimes that your network connection was
  # severed before it could complete.
  class ServerBrokeConnection < RestClient::Exception
    def initialize(message = 'Server broke connection')
      super nil, nil
      self.message = message
    end
  end

  class SSLCertificateNotVerified < RestClient::Exception
    def initialize(message = 'SSL certificate not verified')
      super nil, nil
      self.message = message
    end
  end
end