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
|
require 'postmark/deprecations'
module Postmark
class Error < ::StandardError; end
class HttpClientError < Error
def retry?
true
end
end
class HttpServerError < Error
attr_accessor :status_code, :parsed_body, :body
alias_method :full_response, :parsed_body
def self.build(status_code, body)
parsed_body = Postmark::Json.decode(body) rescue {}
case status_code
when '401'
InvalidApiKeyError.new(401, body, parsed_body)
when '422'
ApiInputError.build(body, parsed_body)
when '500'
InternalServerError.new(500, body, parsed_body)
else
UnexpectedHttpResponseError.new(status_code, body, parsed_body)
end
end
def initialize(status_code = 500, body = '', parsed_body = {})
self.parsed_body = parsed_body
self.status_code = status_code.to_i
self.body = body
message = parsed_body.fetch('Message', "The Postmark API responded with HTTP status #{status_code}.")
super(message)
end
def retry?
5 == status_code / 100
end
end
class ApiInputError < HttpServerError
INACTIVE_RECIPIENT = 406
INVALID_EMAIL_REQUEST = 300
attr_accessor :error_code
def self.build(body, parsed_body)
error_code = parsed_body['ErrorCode'].to_i
case error_code
when INACTIVE_RECIPIENT
InactiveRecipientError.new(error_code, body, parsed_body)
when INVALID_EMAIL_REQUEST
InvalidEmailRequestError.new(error_code, body, parsed_body)
else
new(error_code, body, parsed_body)
end
end
def initialize(error_code = nil, body = '', parsed_body = {})
self.error_code = error_code.to_i
super(422, body, parsed_body)
end
def retry?
false
end
end
class InvalidEmailRequestError < ApiInputError; end
class InactiveRecipientError < ApiInputError
attr_reader :recipients
PATTERNS = [
/Found inactive addresses: (.+?)\. Inactive/,
/these inactive addresses: (.+?)\.?$/
].freeze
def self.parse_recipients(message)
PATTERNS.each do |p|
_, recipients = p.match(message).to_a
next unless recipients
return recipients.split(', ')
end
[]
end
def initialize(*args)
super
@recipients = parse_recipients || []
end
private
def parse_recipients
return unless parsed_body && !parsed_body.empty?
self.class.parse_recipients(parsed_body['Message'])
end
end
class InvalidTemplateError < Error
attr_reader :postmark_response
def initialize(response)
@postmark_response = response
super('Failed to render the template. Please check #postmark_response on this error for details.')
end
end
class TimeoutError < Error
def retry?
true
end
end
class MailAdapterError < Postmark::Error; end
class UnknownMessageType < Error; end
class InvalidApiKeyError < HttpServerError; end
class InternalServerError < HttpServerError; end
class UnexpectedHttpResponseError < HttpServerError; end
# Backwards compatible aliases
Deprecations.add_constants(
:DeliveryError => Error,
:InvalidMessageError => ApiInputError,
:UnknownError => UnexpectedHttpResponseError,
:InvalidEmailAddressError => InvalidEmailRequestError
)
end
|