feat: Backends return Backends.QueryError struct for errors#3552
Conversation
394c535 to
d322ebf
Compare
| ~s(Field "notthere" does not exist.) | ||
| """ | ||
| @spec query_error_message(QueryError.t()) :: String.t() | nil | ||
| def query_error_message(%QueryError{ |
There was a problem hiding this comment.
Error messages could be in the respective backend adaptors but thought it better to keep this in the UI layer.
Ziinc
left a comment
There was a problem hiding this comment.
needs some adjustment for surfacing of errors.
need some distinction between error messages:
- end consumer errors - needs to be generic and shouldn't leak information like underlying backend errors
- operator user - should surface underlying backend errors, but logged out to Logger and surfaced to user via
system.logswith theuser_idmetadata key set. - admin user - surfaced to admin via Logger, such as connection pool errors, which might not have a
user_idassociated, and needs the most detail, on par with operator user
|
|
||
| defp to_query_error(%Ecto.QueryError{message: message} = error) do | ||
| %QueryError{ | ||
| message: message, |
There was a problem hiding this comment.
i think we should restrict what is surfaced to users, in the event that sensitive values get surfaced. things like invalid columns etc are columns are fine, probably can match on the message prefix and give a more generic message for the rest.
There was a problem hiding this comment.
This applies for all backends, not just for postgres
|
Make sense.
How do we identify an operator user? |
00e4105 to
d4102d9
Compare
|
Revised approach:
|
f07cfcb to
82ebf3a
Compare
Does this include API consumers? Example: logflare/test/logflare_web/controllers/endpoints_controller_test.exs Lines 266 to 267 in b1a389c Should this just return a generic error message? |
998e94f to
7ba26a4
Compare
156788b to
01b850d
Compare
5c8be24 to
2909c9f
Compare
Co-authored-by: depthfirst-app[bot] <184448029+depthfirst-app[bot]@users.noreply.github.com>
2909c9f to
ef00e2d
Compare
| {:error, _reason} -> | ||
| conn | ||
| |> json(%{connected?: false, reason: reason}) | ||
| |> json(%{connected?: false}) |
There was a problem hiding this comment.
@msmithstubbs i think for the test connection pathway, we should still show the reason, otherwise users will not know why their connection is failing when adding a backend
There was a problem hiding this comment.
Agreed - figured I'd drop it per the review feedback and pick it up in review.
| @spec ch_query_error_kind(term()) :: QueryError.kind() | ||
| defp ch_query_error_kind(%Ch.Error{code: code}) when code in [47, 62], do: :invalid_query | ||
|
|
||
| defp ch_query_error_kind(%Ch.Error{message: message}) when is_binary(message) do | ||
| if message =~ "UNKNOWN_IDENTIFIER" or message =~ "SYNTAX_ERROR" do | ||
| :invalid_query | ||
| else | ||
| :backend_error | ||
| end | ||
| end |
There was a problem hiding this comment.
we will need to support more official error codes that make sense so that there is better DX when people are crafting queries
There was a problem hiding this comment.
we'll need to narrow them down to error codes relevant to general analytical queries
Add a standard
%QueryError{}struct to be returned by backend adaptors on an unsuccessful query. This allows flexibility on which error messages are logged and which are show to end users.%QueryError{}to normalise the shape of errors returned by backend adaptorsQueryError.kindbased on the backend error message::invalid_query:backend_queryor:connection_error:invalid_query:invalid_queryEndpointsLive
QueryLive
AlertsLive
Closes O11Y-1819 and O11Y-1970