Skip to content

feat: Backends return Backends.QueryError struct for errors#3552

Merged
Ziinc merged 4 commits into
Logflare:mainfrom
msmithstubbs:refactor/backend-query-error
Jun 22, 2026
Merged

feat: Backends return Backends.QueryError struct for errors#3552
Ziinc merged 4 commits into
Logflare:mainfrom
msmithstubbs:refactor/backend-query-error

Conversation

@msmithstubbs

@msmithstubbs msmithstubbs commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

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.

  • Adds %QueryError{} to normalise the shape of errors returned by backend adaptors
  • Updates BigQuery, Postgres, and Clickhouse adaptors to use QueryError when returning an error
  • Adaptors set QueryError.kind based on the backend error message:
    • A missing field error would be :invalid_query
    • Other errors are :backend_query or :connection_error
  • QueryError.log will log errors, excluding :invalid_query
    • User interface layer is not longer responsible for logging backend errors, but may still log user query errors
    • If a user has system_monitoring enabled the logged error messages are included
  • User facing errors only include the backend error message for :invalid_query
CleanShot 2026-06-04 at 16 29 59@2x

EndpointsLive

Slice

QueryLive

CleanShot 2026-06-17 at 11 04 18@2x

AlertsLive

Slice 2

Closes O11Y-1819 and O11Y-1970

@msmithstubbs msmithstubbs changed the title wip: Backends return Backends.QueryError struct for erros wip: Backends return Backends.QueryError struct for errors Jun 2, 2026
@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch 9 times, most recently from 394c535 to d322ebf Compare June 4, 2026 06:23
Comment thread lib/logflare_web/query_error_helpers.ex Outdated
~s(Field "notthere" does not exist.)
"""
@spec query_error_message(QueryError.t()) :: String.t() | nil
def query_error_message(%QueryError{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error messages could be in the respective backend adaptors but thought it better to keep this in the UI layer.

@msmithstubbs msmithstubbs changed the title wip: Backends return Backends.QueryError struct for errors feat: Backends return Backends.QueryError struct for errors Jun 4, 2026
@msmithstubbs
msmithstubbs marked this pull request as ready for review June 4, 2026 06:46
Comment thread lib/logflare_web/live/alerts/alerts_live.ex Outdated
Comment thread lib/logflare/backends/adaptor/clickhouse_adaptor.ex Outdated
Comment thread lib/logflare/backends/adaptor/postgres_adaptor.ex Outdated

@Ziinc Ziinc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.logs with the user_id metadata key set.
  • admin user - surfaced to admin via Logger, such as connection pool errors, which might not have a user_id associated, and needs the most detail, on par with operator user

Comment thread lib/logflare/backends/adaptor/clickhouse_adaptor.ex Outdated
Comment thread lib/logflare/backends/adaptor/bigquery_adaptor.ex Outdated
Comment thread lib/logflare/backends/adaptor/postgres_adaptor.ex Outdated

defp to_query_error(%Ecto.QueryError{message: message} = error) do
%QueryError{
message: message,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies for all backends, not just for postgres

@msmithstubbs

Copy link
Copy Markdown
Contributor Author

Make sense.

operator user - should surface underlying backend errors, but logged out to Logger and surfaced to user via system.logs with the user_id metadata key set.

How do we identify an operator user?

@msmithstubbs
msmithstubbs marked this pull request as draft June 5, 2026 05:44
@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch from 00e4105 to d4102d9 Compare June 5, 2026 05:59
@msmithstubbs

Copy link
Copy Markdown
Contributor Author

Revised approach:

  1. Backend adaptors call Logger for any errors and return QueryError struct
  2. Drop message attr from QueryError
  3. UI layer doesn't log error failures, but handles taking a QueryError struct and determining correct message to show

@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch 4 times, most recently from f07cfcb to 82ebf3a Compare June 11, 2026 00:57
@msmithstubbs

Copy link
Copy Markdown
Contributor Author

@Ziinc

  • end consumer errors - needs to be generic and shouldn't leak information like underlying backend errors

Does this include API consumers? Example:

assert response.error =~
"Multiple CTEs available (first_cte, second_cte, final_data). You must specify which one to query using `f:name`"

Should this just return a generic error message?

@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch 4 times, most recently from 998e94f to 7ba26a4 Compare June 15, 2026 01:37
@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch 7 times, most recently from 156788b to 01b850d Compare June 17, 2026 04:52
@msmithstubbs
msmithstubbs marked this pull request as ready for review June 17, 2026 05:15
@msmithstubbs
msmithstubbs marked this pull request as draft June 17, 2026 05:16
Comment thread lib/logflare/backends/adaptor/bigquery_adaptor.ex
Comment thread lib/logflare/alerting.ex
@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch 8 times, most recently from 5c8be24 to 2909c9f Compare June 18, 2026 02:12
@msmithstubbs
msmithstubbs marked this pull request as ready for review June 18, 2026 02:36
msmithstubbs and others added 4 commits June 22, 2026 09:07
@msmithstubbs
msmithstubbs force-pushed the refactor/backend-query-error branch from 2909c9f to ef00e2d Compare June 21, 2026 23:13
{:error, _reason} ->
conn
|> json(%{connected?: false, reason: reason})
|> json(%{connected?: false})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - figured I'd drop it per the review feedback and pick it up in review.

Comment thread lib/logflare/utils/logger_metadata.ex
Comment on lines +423 to +432
@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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will need to support more official error codes that make sense so that there is better DX when people are crafting queries

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll need to narrow them down to error codes relevant to general analytical queries

@Ziinc
Ziinc merged commit 6ce156c into Logflare:main Jun 22, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants