faunadb-go icon indicating copy to clipboard operation
faunadb-go copied to clipboard

Errors lose nested error descriptions

Open walker-tx opened this issue 4 years ago • 2 comments

Howdy!

I'm using this lib in conjunction w/ Fauna functions to make a GraphQL server. I know Fauna has a product for that - this is more of a learning project than anything else.

Anyway, I've created a create_user function that takes a lot of inspiration from the website's authentication tutorial:

// create_user
Query(
  Lambda(
    ["email", "handle", "password"],
    If(
      Or(
        Exists(Match(Index("user_ref_by_username"), LowerCase(Var("handle")))),
        Exists(Match(Index("users_by_email"), LowerCase(Var("email"))))
      ),
      Abort("the handle or username already exists"),
      Create(Collection("users"), {
        credentials: { password: Var("password") },
        data: {
          id: NewId(),
          email: LowerCase(Var("email")),
          displayName: Var("handle"),
          username: LowerCase(Var("handle"))
        }
      })
    )
  )
)

It creates a user only if the handle and email address is not unique. Otherwise, it Aborts with a message describing the problem. Calling this from the shell is helpful - I get exactly what I expect:

> Call("create_user", ["[email protected]", "Alker", "1234"])
Error: call error
{
  errors: [
    {
      position: [],
      code: 'call error',
      description: 'Calling the function resulted in an error.',
      cause: [
        {
          position: [
            'expr',
            'then'
          ],
          code: 'transaction aborted',
          description: 'the handle or username already exists'
        }
      ]
    }
  ]
}

However, the err from the call via this lib's client.Query(...) method only provides a synthesis of the top-level message:

Response error 400. Errors: [](call error): Calling the function resulted in an error."

This makes it hard to handle the error unambiguously. Does this library support either:

  1. Getting the full response w/ the raw error and its nested errors (or parsed into go struct)?
  2. Getting the error separately but in a form that exposes nested error fields?

If neither, does this make sense to add to the library? If so, where would be a good place to start? I don't mind contributing, but I started learning Go (and FaunaDB) a couple of weeks ago so I'm apprehensive about it at the moment.

walker-tx avatar Dec 16 '20 03:12 walker-tx

Hey @wlockiv. Nice catch. We prepare PR https://github.com/fauna/faunadb-go/pull/135 which fix this but I put this PR on hold since we want some consistency for errors output for all drivers (go, jvm, etc.).

vadimLF avatar Apr 02 '21 08:04 vadimLF

As an extension to this, the Cause field should just be fully recursive.

I have UDFs with many levels of nesting, and this is what I've seen and have been unable to catch:

{
  errors: [
    {
      position: [],
      code: 'call error',
      description: 'Calling the function resulted in an error.',
      cause: [
        {
          position: [
            'expr',
            'in',
            'from',
            1
          ],
          code: 'call error',
          description: 'Calling the function resulted in an error.',
          cause: [
            {
              position: [
                'expr',
                'in',
                'from',
                2
              ],
              code: 'call error',
              description: 'Calling the function resulted in an error.',
              cause: [
                {
                  position: [
                    'expr',
                    'in',
                    'from',
                    2,
                    'lambda'
                  ],
                  code: 'invalid argument',
                  description: 'Lambda expects an array with 5 elements. Array contains 4.'
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Since ValidationFailure is just the same as QueryError minus Cause, I think it would be best to change the type of Cause to []QueryError instead of []ValidationFailure.

ssttevee avatar Jun 12 '21 01:06 ssttevee