square / square/square-ruby-sdk

A 503 response raises ArgumentError instead of ServiceUnavailableError

Open
#230 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
75
Forks
47
Avg merge
2h 10m
Merged PRs (30d)
1

Description

Summary

Every HTTP error status is turned into an exception by Square::Errors::ResponseError.subclass_for_code(code) and raised as error_class.new(response.body, code: code) (e.g. lib/square/payments/client.rb). All the classes that method returns inherit ResponseError, whose initializer accepts (msg, code:) — except ServiceUnavailableError, which inherits plain ApiError (< StandardError):

# lib/square/errors/server_error.rb
module Square
  module Errors
    class ServerError < ResponseError
    end

    class ServiceUnavailableError < ApiError
    end
  end
end

So when the API answers 503, the SDK crashes while constructing its own exception, and callers get an ArgumentError instead of the ServiceUnavailableError they are told to rescue:

require "square"

Square::Errors::ResponseError.subclass_for_code(503).new("body", code: 503)
# => ArgumentError: wrong number of arguments (given 2, expected 0..1)

In practice, any endpoint call during a Square 503 raises:

ArgumentError: wrong number of arguments (given 2, expected 0..1)
  .../square.rb-45.0.2.20260122/lib/square/payments/client.rb:130:in 'Exception#initialize'
  .../square.rb-45.0.2.20260122/lib/square/payments/client.rb:130:in 'Square::Payments::Client#create'

This is painful for payment flows specifically: a 503 on payments.create is an ambiguous outcome that client code needs to catch and handle deliberately, and an ArgumentError escaping from inside the SDK is easy to misclassify as an application bug.

Affected versions

Reproduced on square.rb 45.0.2.20260122; the hierarchy is unchanged on current main (lib/square/errors/server_error.rb). Introduced with the error-class hierarchy from #196.

Suggested fix

Make ServiceUnavailableError inherit ResponseError (or give it a (msg, code:) initializer) so subclass_for_code's uniform new(body, code:) call works for 503 like it does for every other status. Since the SDK is Fern-generated, presumably a generator-side change.

Workaround

We currently patch the signature in an initializer:

module Square
  module Errors
    class ServiceUnavailableError
      attr_reader :code

      def initialize(msg = nil, code: nil)
        @code = code
        super(msg)
      end
    end
  end
end

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in lib/square/errors/server_error.rb and trace ResponseError.subclass_for_code(code) plus the uniform construction call in lib/square/payments/client.rb. Confirm how the Fern-generated error hierarchy is produced, then make ServiceUnavailableError accept the same response body and code arguments; done when a 503 raises ServiceUnavailableError rather than ArgumentError.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
api, backend-api-design
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.