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

Implement transparent client pattern and middleware error handling #147

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

andrii-balitskyi
Copy link
Collaborator

@andrii-balitskyi andrii-balitskyi commented Oct 31, 2024

Closes #137

  • Add response middleware
  • Remove base client
  • Remove request_seam methods in favour of using faraday client directly
  • Support [] syntax on DeepHashAccessor instances
  • Adjust action attempt polling to the new logic
  • Bump the generator to 1.14.10 to adjust routes
  • Fix tests

action_attempt_id: action_attempt.action_attempt_id
}
)
response = client.post("/action_attempts/get", {action_attempt_id: action_attempt.action_attempt_id})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
response = client.post("/action_attempts/get", {action_attempt_id: action_attempt.action_attempt_id})
response = client.get("/action_attempts/get", {action_attempt_id: action_attempt.action_attempt_id})

@client = client || Seam::Http::Request.create_faraday_client(@endpoint, @auth_headers, faraday_options,
faraday_retry_options)

initialize_routes(client: @client, defaults: @defaults)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this do? Why is it defined as a private function but called here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize_routes is an internal method to set up route clients by making available @client and @defaults for them. SingleWorkspace can access private initialize_routes because Routes module gets included in the class. While the method will exist on instances, being private it can only be called internally (inside the class/module methods) and not from outside code, unlike public methods like 'devices', 'access_codes' etc. which can be called by anyone using the instance.

Comment on lines +61 to +65
body = begin
JSON.parse(env.body)
rescue
{}
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't assume the response is always JSON. It's possible for things in front of the API to return errors that are not JSON like Bad Gateway or Service Unavailable. I checked and the python SDK has the same assumption: https://github.com/seamapi/python/blob/7b62fa7eab7094d36af6f74465d4703da94d4330/seam/client.py#L64

We may need to replicate this logic in all the SDKs: https://github.com/seamapi/javascript-http/blob/8178e4f42e89198defdcda0a83a7b6ed4b482066/src/lib/seam/connect/error-interceptor.ts#L34-L61

I'm not sure we should keep the default "unknown" values either: the error needs to have a type and a message to be considered a Seam error.

Basically:

  1. Check for 401 status code and throw our custom SeamHttpUnauthorizedError
  2. Try to determine if the error response can reasonably assumed to be a JSON error from the Seam API and throw it as either a SeamHttpInvalidInputError or the generic SeamHttpApiError. We can still default
  3. Otherwise, we just throw the error provided by the underlying http client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement transparent client pattern and middleware error handling
3 participants