Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ErrorObject to StripeError exceptions #811

Merged
merged 1 commit into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
ob-stripe marked this conversation as resolved.
Show resolved Hide resolved

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
ob-stripe marked this conversation as resolved.
Show resolved Hide resolved
@values[:error]
end

# A human readable description of the error.
def error_description
@values[:error_description]
end
end
end
14 changes: 14 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,13 @@ 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 +126,12 @@ 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