Errors: Value not found at path

Currently using Basic authorization and a Query defined in schema as:

userFindById (uid: String!): User @resolver (name: "user_find_by_id")

I have a function:

name: "user_find_by_id",
    body: Query(
        Lambda(
            ["uid"],
            Let(
                {
                    match: Match(Index("user_find_by_id"), Var("uid")),
                    user: If(Exists(Var("match")), Get(Var("match")), "false"),
                },
                {   
                     user: Select(['data', 'username'], Var("user"))
                }
            )
        )
    )

which uses an index:

name: "user_find_by_id",
  source: Collection("User"),
  unique: false,
  terms: [
    {
      field: ["ref"]
    }
  ]

However, trying with an existing User document:

{
  userFindById(uid: "290125575057572353") {
    username
  }
}

on document:

{
  "ref": Ref(Collection("User"), "290125575057572353"),
  "ts": 1612944159470000,
  "data": {
    "active": true,
    "username": "Test1",
    "description": "R hander",
    "email": "t1@t1.com",
    "mobile": "+65 1111"
  }
}

in PG I get:

{
  "errors": [
    {
      "message": "Value not found at path [data,username].",
      "extensions": {
        "code": "value not found"
      }
    }
  ]
}

How do I need to change the function to be able to reference fields in the User collection?
Thanks …

It looks like there are several problems.

Let’s start with the index. Why do you feel the need to create an index that has one term, which is each document’s reference? A document’s reference is its primary key; if you have the reference, you can simply call Get.

Seperately, the Match statement in your function only passed the document ID portion of a reference. That cannot possibly match a full reference. The reference for your example document is Ref(Collection("User"), "290125575057572353"), not 290125575057572353.

Assuming that your index lookup was working, you are calling Exists on the result of Match. Match returns a set reference: that always exists, but might contain 0 or more elements.

Your function uses If, presumably to guard against errors, but only specifies false if the user document does not exist. But then it attempts to get the username field from a document that might be false.

It seems like you should change the function body to this instead:

Let(
  {
    userref: Ref(Collection("User"), Var("uid")),
    username: If(
      Exists(Var("userref")),
      Select(["data", "username"], Get(Var("userref"))),
      "User does not exist"
    ),
  },
  { username: Var("username") }
)

As you can see, no index was required, and the function is now all about acquiring the username, if the provided document ID refers to an existing document in the Users collection.

Note that you can test your function in the Shell, by executing this query:

Call("user_find_by_id", "290125575057572353")

That lets you test the function directly, without involving GraphQL.

Apologies for slow response. Attempting to resolve this issue first has made it easier for me to more clearly respond here.

One aspect of that issue is that I should be using the fauna generated function and not a UDF as I have here because I was operating under the mistaken idea that I could not use security features (tokens) without a UDF.

Why do you feel the need to create an index that has one term, which is each document’s reference?

For the reason above, I was copying the format from the fauna generated function, which simply required a doc ref. However, your comments re: ‘Get’, ‘match’ against a full reference, Exists and If, in the context of a UDF, are all appreciated and noted.

Whilst I’m not relying on this particular UDF at this moment I will test your suggestion as it, and your other suggestions, are all relevant to UDFs I may create in future.

Thanks very much for your instructive response …

1 Like