Skip to content

Commit

Permalink
Add ErrorObject to StripeError exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ob-stripe committed Aug 16, 2019
1 parent 56ea5f4 commit 9d26192
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 8 deletions.
1 change: 1 addition & 0 deletions lib/stripe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
require "stripe/stripe_object"
require "stripe/stripe_response"
require "stripe/list_object"
require "stripe/error_object"
require "stripe/api_resource"
require "stripe/singleton_api_resource"
require "stripe/webhook"
Expand Down
94 changes: 94 additions & 0 deletions lib/stripe/error_object.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# frozen_string_literal: true

module Stripe
# Represents an error object as returned by the API.
#
# @see https://stripe.com/docs/api/errors
class ErrorObject < StripeObject
# Unlike other objects, we explicitly declare getter methods here. This
# is because the API doesn't return `null` values for fields on this
# object, rather the fields are omitted entirely. Not declaring the getter
# methods would cause users to run into `NoMethodError` exceptions and
# get in the way of generic error handling.

# For card errors, the ID of the failed charge.
def charge
@values[:charge]
end

# For some errors that could be handled programmatically, a short string
# indicating the error code reported.
def code
@values[:code]
end

# For card errors resulting from a card issuer decline, a short string
# indicating the card issuer's reason for the decline if they provide one.
def decline_code
@values[:decline_code]
end

# A URL to more information about the error code reported.
def doc_url
@values[:doc_url]
end

# A human-readable message providing more details about the error. For card
# errors, these messages can be shown to your users.
def message
@values[:message]
end

# If the error is parameter-specific, the parameter related to the error.
# For example, you can use this to display a message near the correct form
# field.
def param
@values[:param]
end

# The PaymentIntent object for errors returned on a request involving a
# PaymentIntent.
def payment_intent
@values[:payment_intent]
end

# The PaymentMethod object for errors returned on a request involving a
# PaymentMethod.
def payment_method
@values[:payment_method]
end

# The SetupIntent object for errors returned on a request involving a
# SetupIntent.
def setup_intent
@values[:setup_intent]
end

# The source object for errors returned on a request involving a source.
def source
@values[:source]
end

# The type of error returned. One of `api_connection_error`, `api_error`,
# `authentication_error`, `card_error`, `idempotency_error`,
# `invalid_request_error`, or `rate_limit_error`.
def type
@values[:type]
end
end

# Represents on OAuth error returned by the OAuth API.
#
# @see https://stripe.com/docs/connect/oauth-reference#post-token-errors
class OAuthErrorObject < StripeObject
# A unique error code per error type.
def error
@values[:error]
end

# A human readable description of the error.
def error_description
@values[:error_description]
end
end
end
12 changes: 12 additions & 0 deletions lib/stripe/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class StripeError < StandardError
attr_accessor :response

attr_reader :code
attr_reader :error
attr_reader :http_body
attr_reader :http_headers
attr_reader :http_status
Expand All @@ -27,6 +28,12 @@ def initialize(message = nil, http_status: nil, http_body: nil,
@json_body = json_body
@code = code
@request_id = @http_headers[:request_id]
@error = construct_error_object
end

def construct_error_object
return nil if @json_body.nil? || !@json_body.key?(:error)
ErrorObject.construct_from(@json_body[:error])
end

def to_s
Expand Down Expand Up @@ -118,6 +125,11 @@ def initialize(code, description, http_status: nil, http_body: nil,
json_body: json_body, http_headers: http_headers,
code: code)
end

def construct_error_object
return nil if @json_body.nil?
OAuthErrorObject.construct_from(@json_body)
end
end

# InvalidClientError is raised when the client doesn't belong to you, or
Expand Down
37 changes: 29 additions & 8 deletions test/stripe/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,37 @@

module Stripe
class StripeErrorTest < Test::Unit::TestCase
context "#to_s" do
should "convert to string" do
e = StripeError.new("message")
assert_equal "message", e.to_s
context "StripeError" do
context "#initialize" do
should "initialize error if json_body is set" do
e = StripeError.new("message", json_body: { error: { code: "some_error" } })
assert_not_nil e.error
assert_equal "some_error", e.error.code
assert_nil e.error.charge
end
end

context "#to_s" do
should "convert to string" do
e = StripeError.new("message")
assert_equal "message", e.to_s

e = StripeError.new("message", http_status: 200)
assert_equal "(Status 200) message", e.to_s

e = StripeError.new("message", http_status: 200)
assert_equal "(Status 200) message", e.to_s
e = StripeError.new("message", http_status: nil, http_body: nil, json_body: nil, http_headers: { request_id: "request-id" })
assert_equal "(Request request-id) message", e.to_s
end
end
end

e = StripeError.new("message", http_status: nil, http_body: nil, json_body: nil, http_headers: { request_id: "request-id" })
assert_equal "(Request request-id) message", e.to_s
context "OAuth::OAuthError" do
context "#initialize" do
should "initialize error if json_body is set" do
e = OAuth::OAuthError.new("message", "description", json_body: { error: "some_oauth_error" })
assert_not_nil e.error
assert_equal "some_oauth_error", e.error.error
end
end
end
end
Expand Down

0 comments on commit 9d26192

Please sign in to comment.