Graphql-engine: Hasura doesn't show RAISE EXCEPTION message from postgres function

Created on 25 Jul 2019  ·  22Comments  ·  Source: hasura/graphql-engine

It's common to make some checks in triggers and RAISE NOTICE or EXCEPTION and provided message went to postgres log. Can we somehow provide this message to the client, instead poor Uncaught (in promise) Error: GraphQL error: postgres query error

server high triag2-needs-rfc

Most helpful comment

@abn This is definitely something that we want to implement but we haven't added it to our pipeline yet. Hopefully, we can get this out in a couple of releases.

Any update on this feature?
This would be great

This is a must feature.We really need this feature.
When it will be available?

All 22 comments

Any update? I think this is really needed for any kind of serious app with validations.

Capturing postgres errors and propagating them to the client side is easy however we shouldn't be capturing every error, only those that are meant for the client.

The question is how do we distinguish these errors? Luckily Postgres lets you define custom error codes (through SQLSTATE). So maybe we can provide a server side flag, say, CAPTURE_SQLSTATE? The server will capture errors with that particular error state and propagate them to the client. Your validation logic should use this error code if you want to propagate the error to the client.

@0x777 that would be great. It would also be helpful if that check support a prefix or a pattern/mask to be configured, this could be in accordance to what is specified in the documentation.

When specifying an error code by SQLSTATE code, you are not limited to the predefined error codes, but can select any error code consisting of five digits and/or upper-case ASCII letters, other than 00000. It is recommended that you avoid throwing error codes that end in three zeroes, because these are category codes and can only be trapped by trapping the whole category.

In our use case today, we have a helper function (example below) that raises all exceptions that we want to propagate to the client. We use a prefix (eg: C0) to the code in order to indicate such application errors.

CREATE FUNCTION errors.raise(
  code_    TEXT DEFAULT 'C0500',
  message_ TEXT DEFAULT 'Something went wrong while processing your request',
  hint_    TEXT DEFAULT 'Try again later'
) RETURNS VOID
  LANGUAGE plpgsql
  IMMUTABLE STRICT PARALLEL SAFE AS
$function$
BEGIN
  RAISE EXCEPTION USING ERRCODE = code_, MESSAGE = message_, HINT = hint_;
END;
$function$;

It would really helpful if such a usage pattern (including the propagation of HINT) could be supported in the solution for this issue.

@0x777 @dsandip was there any movement/update on this one?

@abn This is definitely something that we want to implement but we haven't added it to our pipeline yet. Hopefully, we can get this out in a couple of releases.

@0x777 that would be amazing; happy to test any PR branches etc or contribute in a similar fashion. Right now we are left with some "string match and guess work" logic in the front end to determine how best to feedback to the user.

Any update on this?
This feature is pretty much needed.

https://blog.hasura.io/postgres-triggers-on-graphql-mutations-682bf48db023/

This blog post raises the exception and is received by the client, but the same doesn't happen on our hasura client front

Cause Hasura doesn't show RAISE EXCEPTION message, maybe I should create a new table to store the error messages for different tables, and then return NULL. 😁 😅

It raises proper exceptions if you use hasura-admin-secret but will fail if you use jwt authorization.

Any progress on this one? With iffy inbound data into our database (i.e. any realistic use case) we need to be able to handle cases where data is unavailable for a GraphQL query. Postgresql exceptions seem to be the way to go in order to handle these.

@dvasdekis This issue is something we would like to pick up and we are figuring out its priority.

I'm having the same problem of @rohit-32... if hasura has a jwt configured and defined Authorization header, Graphql show as answer postgres query error not throwing the error.

Contextualizing: I have a trigger function, that realizes some checks and if it is invalid then raise an exception.

Captura de Tela 2020-02-14 às 23 46 21

http log:

{
  "type":"http-log",
  "timestamp":"2020-02-15T02:43:52.897+0000",
  "level":"error",
  "detail":{
    "operation":{
      "user_vars":{
        "x-hasura-role":"user",
        "x-hasura-user-id":"2f589e70-c029-4aed-a4de-f06620444fa7"
      },
      "error":{
        "internal":{
          "statement":"WITH \"public_user_groups__mutation_result_alias\" AS (INSERT INTO \"hdb_views\".\"user__insert__public__user_groups\" ( \"updated_at\", \"created_at\", \"quotas\", \"id\", \"group_id\", \"user_id\" ) VALUES (DEFAULT, DEFAULT, $2, DEFAULT, $1, ((current_setting('hasura.user')::json->>'x-hasura-user-id'))::uuid)  RETURNING * ) SELECT  json_build_object('affected_rows', (SELECT  COUNT(*)  FROM \"public_user_groups__mutation_result_alias\"      ) )        ",
          "prepared":true,
          "error":{
            "exec_status":"FatalError",
            "hint":null,
            "message":"CURRENT QUOTA VALUE IS EXCEEDING THE CURRENT QUOTA (MAX_QUOTAS (5) - TO_INSERT (4))",
            "status_code":"P0001",
            "description":null
          },
          "arguments":[
            "(Oid 0,Just (\"5803e53d-55e1-4e32-bd47-581d330b4fc5\",Text))",
            "(Oid 23,Just (\"\\NUL\\NUL\\NUL\\EOT\",Binary))"
          ]
        },
        "path":"$.selectionSet.insert_user_groups.args.objects",
        "error":"postgres query error",
        "code":"unexpected"
      },
      "request_id":"2e94b56d-2702-4b30-9796-9035d669fa29",
      "response_size":922,
      "query":{
        "variables":{
          "groupId":"5803e53d-55e1-4e32-bd47-581d330b4fc5"
        },
        "operationName":"enterGroup",
        "query":"mutation enterGroup($groupId: uuid) {\n  insert_user_groups(objects: {group_id: $groupId, quotas: 4}) {\n    affected_rows\n  }\n}\n"
      }
    },
    "http_info":{
      "status":200,
      "http_version":"HTTP/1.1",
      "url":"/v1/graphql",
      "ip":"172.19.0.1",
      "method":"POST",
      "content_encoding":null
    }
  }
}

trigger: https://gist.github.com/mandado/2d074b1d975a026111b224e96e62bb11

Same here. We're having a BEFORE INSERT ON trigger on a table that makes certain validations and raises an exception when the insert operation is not allowed. This ends up as

path: "$.selectionSet.insert_entity.args.objects"
code: "unexpected"
message: "postgres query error"

in the response. The raised exception message is no where to be seen, which we'd like.

Having the same issue when I include "x-hasura-role" as header in dashboard I get

{ "errors": [ { "extensions": { "path": "$", "code": "unexpected" }, "message": "postgres query error" } ] }

Would it be possible to whitelist which errors code(prefix?) are allowed to be shown client side? Like we do for graphql queries.

--postgres-errors-prefix-whitelist=TXXA
HASURA_POSTGRES_ERROS_PREFIX_WHITELIST=TXXA

It seems to be fixed in the last Hasura release https://github.com/hasura/graphql-engine/releases/tag/v1.2.0-beta.5
You have to put HASURA_GRAPHQL_DEV_MODE as true or start the server with --dev-mode flag.

I'm wondering why they consider this a dev setting while our usecase is pretty common ?

Having the same issue here.
@DavoCg Maybe it's for security purpose. I don't want users can see the table structures too. But it's really really helpful if the errcodes can be exposed.

@abn This is definitely something that we want to implement but we haven't added it to our pipeline yet. Hopefully, we can get this out in a couple of releases.

Any update on this feature?
This would be great

@abn This is definitely something that we want to implement but we haven't added it to our pipeline yet. Hopefully, we can get this out in a couple of releases.

Any update on this feature?
This would be great

This is a must feature.We really need this feature.
When it will be available?

anything new on this feature request?

I guess you can use Class 22 — Data Exception error codes

raise exception like this
RAISE EXCEPTION USING ERRCODE= '22000', MESSAGE= 'business logic error message';

and the client will always receive
{
"errors": [
{
"extensions": {
"path": "$",
"code": "data-exception"
},
"message": "business logic error message"
}
]
}

https://www.postgresql.org/docs/current/errcodes-appendix.html

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Fortidude picture Fortidude  ·  3Comments

revskill10 picture revskill10  ·  3Comments

shahidhk picture shahidhk  ·  3Comments

lishine picture lishine  ·  3Comments

sachaarbonel picture sachaarbonel  ·  3Comments