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

Refactor errors #96

Merged
merged 27 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a1c0875
Rename SeamHttpApiError to HttpApiError
andrii-balitskyi Aug 20, 2024
7640fdf
Rename SeamHttpUnauthorizedError to UnauthorizedError
andrii-balitskyi Aug 20, 2024
d99db3b
Rename UnauthorizedError to HttpUnauthorizedError
andrii-balitskyi Aug 20, 2024
cfacfef
Rename SeamHttpInvalidInputError to InvalidInputError
andrii-balitskyi Aug 20, 2024
64c7ebd
Rename SeamActionAttemptError to ActionAttemptError
andrii-balitskyi Aug 20, 2024
df81b94
Rename SeamActionAttemptFailedError to ActionAttemptFailedError
andrii-balitskyi Aug 20, 2024
adabd21
More SeamActionAttemptFailedError rename
andrii-balitskyi Aug 20, 2024
4fb1ca3
Rename SeamActionAttemptTimeoutError to ActionAttemptTimeoutError
andrii-balitskyi Aug 20, 2024
88ed48d
ci: Format code
seambot Aug 20, 2024
62e8761
Fix tests, move SeamInvalidTokenError to Http module
andrii-balitskyi Aug 20, 2024
db2129a
Rename Http to Client and HttptMultiWorkspace to ClientMultiWorkspace
andrii-balitskyi Sep 19, 2024
b0d8526
Leftover renames
andrii-balitskyi Sep 19, 2024
5f69fd5
Renames in lib/seam.rb
andrii-balitskyi Sep 19, 2024
84b1b3c
Move http errors to http module, fix specs
andrii-balitskyi Sep 19, 2024
a7c1a17
Merge branch 'main' of github.com:seamapi/ruby-next into refactor-errors
andrii-balitskyi Sep 19, 2024
ec8edae
Put action attempt errors under errors module
andrii-balitskyi Sep 19, 2024
6a590df
Rename SeamWebhook to Webhook
andrii-balitskyi Oct 3, 2024
e8538f0
Make Http a module with http errors, SingleWorkspace and MultiWorkspa…
andrii-balitskyi Oct 3, 2024
4defdc8
Bump generator to 1.14.5 to put resource related stuff under Resource…
andrii-balitskyi Oct 3, 2024
aafc34f
Alias factory methods
andrii-balitskyi Oct 3, 2024
2d3558f
Clean up public exports
andrii-balitskyi Oct 3, 2024
8f192d3
Bump generator to include base client and resource imports in the routes
andrii-balitskyi Oct 3, 2024
5e105ce
Move action attempt errors under WaitForActionAttempt module
andrii-balitskyi Oct 3, 2024
a5c2c1d
Merge branch 'main' of github.com:seamapi/ruby-next into refactor-errors
andrii-balitskyi Oct 3, 2024
644f08b
Remove Http prefix from http errors
andrii-balitskyi Oct 10, 2024
781f22b
Reduce nesting of wait for action attempt errors
andrii-balitskyi Oct 10, 2024
fc69841
Refactor SeamOptions and SeamAuth
andrii-balitskyi Oct 10, 2024
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
18 changes: 4 additions & 14 deletions lib/seam.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
# frozen_string_literal: true

require_relative "seam/version"
require_relative "seam/lts_version"
require_relative "seam/default_endpoint"
require_relative "seam/request"
require_relative "seam/logger"
require_relative "seam/http"
require_relative "seam/http_multi_workspace"
require_relative "seam/base_client"
require_relative "seam/base_resource"
require_relative "seam/errors"
require_relative "seam/seam_webhook"

require_relative "seam/routes/resources/index"
require_relative "seam/routes/clients/index"
require_relative "seam/wait_for_action_attempt"
require_relative "seam/webhook"

module Seam
def self.new(**args)
Http.new(**args)
end

def self.from_api_key(api_key, endpoint: nil, wait_for_action_attempt: false, debug: false)
new(api_key: api_key, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
Http.from_api_key(api_key, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
end

def self.from_personal_access_token(personal_access_token, workspace_id, endpoint: nil, wait_for_action_attempt: false, debug: false)
new(personal_access_token: personal_access_token, workspace_id: workspace_id, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
Http.from_personal_access_token(personal_access_token, workspace_id, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
end

def self.lts_version
Expand Down
78 changes: 40 additions & 38 deletions lib/seam/base_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,61 @@
require_relative "deep_hash_accessor"

module Seam
class BaseResource
attr_accessor :data, :client
module Resources
class BaseResource
attr_accessor :data, :client

def initialize(data, client = nil)
@data = data
@client = client
def initialize(data, client = nil)
@data = data
@client = client

@data.each do |key, value|
value = Seam::DeepHashAccessor.new(value) if value.is_a?(Hash)
instance_variable_set(:"@#{key}", value)
@data.each do |key, value|
value = Seam::DeepHashAccessor.new(value) if value.is_a?(Hash)
instance_variable_set(:"@#{key}", value)
end
end
end

def update_from_response(data)
@data = data
@data.each do |key, value|
instance_variable_set(:"@#{key}", value)
def update_from_response(data)
@data = data
@data.each do |key, value|
instance_variable_set(:"@#{key}", value)
end
end
end

def self.load_from_response(data, client = nil)
if data.is_a?(Array)
data.map { |d| new(d, client) }
else
new(data, client)
def self.load_from_response(data, client = nil)
if data.is_a?(Array)
data.map { |d| new(d, client) }
else
new(data, client)
end
end
end

def inspect
"<#{self.class.name}:#{"0x00%x" % (object_id << 1)}\n" + # rubocop:disable Style/StringConcatenation, Style/FormatString
instance_variables
.map { |k| k.to_s.sub("@", "") }
.filter { |k| k != "data" and k != "client" and respond_to? k }
.map { |k| " #{k}=#{send(k).inspect}" }
.join("\n") + ">"
end
def inspect
"<#{self.class.name}:#{"0x00%x" % (object_id << 1)}\n" + # rubocop:disable Style/StringConcatenation, Style/FormatString
instance_variables
.map { |k| k.to_s.sub("@", "") }
.filter { |k| k != "data" and k != "client" and respond_to? k }
.map { |k| " #{k}=#{send(k).inspect}" }
.join("\n") + ">"
end

def self.date_accessor(*attrs)
attrs.each do |attr|
define_method(attr) do
value = instance_variable_get(:"@#{attr}")
def self.date_accessor(*attrs)
attrs.each do |attr|
define_method(attr) do
value = instance_variable_get(:"@#{attr}")

raise "No value for #{attr} set" if value.nil?
raise "No value for #{attr} set" if value.nil?

parse_datetime(value)
parse_datetime(value)
end
end
end
end

protected
protected

def parse_datetime(value)
Time.parse(value)
def parse_datetime(value)
Time.parse(value)
end
end
end
end
68 changes: 0 additions & 68 deletions lib/seam/errors.rb

This file was deleted.

4 changes: 2 additions & 2 deletions lib/seam/helpers/action_attempt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def self.wait_until_finished(action_attempt, client, timeout: nil, polling_inter
sleep(polling_interval)
time_waiting += polling_interval

raise Errors::SeamActionAttemptTimeoutError.new(action_attempt, timeout) if time_waiting > timeout
raise Seam::Http::WaitForActionAttempt::TimeoutError.new(action_attempt, timeout) if time_waiting > timeout

action_attempt = update_action_attempt(action_attempt, client)
end

raise Errors::SeamActionAttemptFailedError.new(action_attempt) if action_attempt.status == "error"
raise Seam::Http::WaitForActionAttempt::FailedError.new(action_attempt) if action_attempt.status == "error"

action_attempt
end
Expand Down
65 changes: 36 additions & 29 deletions lib/seam/http.rb
Original file line number Diff line number Diff line change
@@ -1,44 +1,51 @@
# frozen_string_literal: true

require_relative "parse_options"
require_relative "routes/routes"
require_relative "http_single_workspace"

module Seam
class Http
include Seam::Routes

attr_accessor :defaults

def initialize(api_key: nil, personal_access_token: nil, workspace_id: nil, endpoint: nil,
wait_for_action_attempt: true, debug: false)
options = SeamOptions.parse_options(api_key: api_key, personal_access_token: personal_access_token, workspace_id: workspace_id, endpoint: endpoint)
@endpoint = options[:endpoint]
@auth_headers = options[:auth_headers]
@debug = debug
@wait_for_action_attempt = wait_for_action_attempt
@defaults = Seam::DeepHashAccessor.new({"wait_for_action_attempt" => wait_for_action_attempt})
module Http
def self.new(**args)
Http::SingleWorkspace.new(**args)
end

def lts_version
Seam::LTS_VERSION
def self.from_api_key(api_key, endpoint: nil, wait_for_action_attempt: false, debug: false)
Http::SingleWorkspace.from_api_key(api_key, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
end

def request_seam_object(method, path, klass, inner_object, config = {})
response = request_seam(method, path, config)
def self.from_personal_access_token(personal_access_token, workspace_id, endpoint: nil, wait_for_action_attempt: false, debug: false)
Http::SingleWorkspace.from_personal_access_token(personal_access_token, workspace_id, endpoint: endpoint, wait_for_action_attempt: wait_for_action_attempt, debug: debug)
end

class HttpApiError < StandardError
andrii-balitskyi marked this conversation as resolved.
Show resolved Hide resolved
attr_reader :code, :status_code, :request_id, :data

data = response[inner_object]
def initialize(error, status_code, request_id)
super(error[:message])
@code = error[:type]
@status_code = status_code
@request_id = request_id
@data = error[:data]
end
end

klass.load_from_response(data, self)
class HttpUnauthorizedError < HttpApiError
andrii-balitskyi marked this conversation as resolved.
Show resolved Hide resolved
def initialize(request_id)
super({type: "unauthorized", message: "Unauthorized"}, 401, request_id)
end
end

def request_seam(method, path, config = {})
Seam::Request.new(
auth_headers: @auth_headers,
endpoint: @endpoint,
debug: @debug
).perform(
method, path, config
)
class InvalidInputError < HttpApiError
attr_reader :validation_errors

def initialize(error, status_code, request_id)
super(error, status_code, request_id)
@code = "invalid_input"
@validation_errors = error["validation_errors"] || {}
end

def get_validation_error_messages(param_name)
@validation_errors.dig(param_name, "_errors") || []
end
end
end
end
75 changes: 39 additions & 36 deletions lib/seam/http_multi_workspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,56 @@
require_relative "parse_options"
require_relative "lts_version"
require_relative "auth"
require_relative "request"

module Seam
class HttpMultiWorkspace
attr_reader :wait_for_action_attempt, :defaults
module Http
class MultiWorkspace
attr_reader :wait_for_action_attempt, :defaults

def initialize(personal_access_token:, endpoint: nil, wait_for_action_attempt: true)
@wait_for_action_attempt = wait_for_action_attempt
@defaults = {"wait_for_action_attempt" => wait_for_action_attempt}
@endpoint = SeamOptions.get_endpoint(endpoint)
@auth_headers = SeamAuth.get_auth_headers_for_multi_workspace_personal_access_token(personal_access_token)
end
def initialize(personal_access_token:, endpoint: nil, wait_for_action_attempt: true)
@wait_for_action_attempt = wait_for_action_attempt
@defaults = {"wait_for_action_attempt" => wait_for_action_attempt}
@endpoint = SeamOptions.get_endpoint(endpoint)
@auth_headers = SeamAuth.get_auth_headers_for_multi_workspace_personal_access_token(personal_access_token)
end

def self.lts_version
Seam::LTS_VERSION
end
def self.lts_version
Seam::LTS_VERSION
end

def lts_version
Seam::LTS_VERSION
end
def lts_version
Seam::LTS_VERSION
end

def workspaces
@workspaces ||= WorkspacesProxy.new(Seam::Clients::Workspaces.new(self))
end
def workspaces
@workspaces ||= WorkspacesProxy.new(Seam::Clients::Workspaces.new(self))
end

def self.from_personal_access_token(personal_access_token, endpoint: nil, wait_for_action_attempt: true)
new(
personal_access_token: personal_access_token,
endpoint: endpoint,
wait_for_action_attempt: wait_for_action_attempt
)
end
def self.from_personal_access_token(personal_access_token, endpoint: nil, wait_for_action_attempt: true)
new(
personal_access_token: personal_access_token,
endpoint: endpoint,
wait_for_action_attempt: wait_for_action_attempt
)
end

def request_seam_object(method, path, klass, inner_object, config = {})
response = request_seam(method, path, config)
def request_seam_object(method, path, klass, inner_object, config = {})
response = request_seam(method, path, config)

data = response[inner_object]
data = response[inner_object]

klass.load_from_response(data, self)
end
klass.load_from_response(data, self)
end

def request_seam(method, path, config = {})
Seam::Request.new(
auth_headers: @auth_headers,
endpoint: @endpoint
).perform(
method, path, config
)
def request_seam(method, path, config = {})
Seam::Request.new(
auth_headers: @auth_headers,
endpoint: @endpoint
).perform(
method, path, config
)
end
end
end
end
Expand Down
Loading