clerk-sdk-ruby icon indicating copy to clipboard operation
clerk-sdk-ruby copied to clipboard

The message contents of Clerk:Errors is a serialized Ruby object as a string

Open yoeun opened this issue 1 year ago • 0 comments

I ran into this issue trying to match the error code form_identifier_exists in my Clerk::Errors::Fatal handler.

begin
  clerk_sdk.users.create(....)
rescue Clerk::Errors::Fatal => e
  e.errors                # NoMethodError for 'errors'
  e.message               # returns a what looks like Ruby hash object (but actually a string)
  e.message['error']      # NoMethodError for '[]'
end

I think the culprit is this line:

https://github.com/clerk/clerk-sdk-ruby/blob/25c2c18b57611dd79bfc9c03733fb2519ebaaab6/lib/clerk/sdk.rb#L100

It takes the JSON response of the HTTP API and parses it into a ruby object. Then it passes this object into Errors::Fatal.new().

https://github.com/clerk/clerk-sdk-ruby/blob/25c2c18b57611dd79bfc9c03733fb2519ebaaab6/lib/clerk/sdk.rb#L114

The end result is that the error object now has a message that looks like this:

{\"errors\"=>[{\"message\"=>\"That email address is taken. Please try another.\", \"long_message\"=>\"That email address is taken. Please try another.\", \"code\"=>\"form_identifier_exists\", \"meta\"=>{\"param_name\"=>\"email_address\"}}], \"clerk_trace_id\"=>\"...\", \"status\"=>422}

So it's not a ruby object or a JSON string, but a string representation of a ruby object.

There are ways to get around this by using eval() or replacing => with : and parsing as JSON, but I expected the JSON from the HTTP API to be mapped to properties in the Clerk::Errors::Fatal object.

rescue Clerk::Errors::Fatal => e
  # option 1: save JSON parsed HTTP error to `errors` property so I can inspect it myself
  e.errors[0].code

  # option 2: flatten HTTP response to single error
  e.code
end

yoeun avatar Dec 08 '23 00:12 yoeun