From bf90f954435d34f91f3c535366a912f02416040c Mon Sep 17 00:00:00 2001 From: Laurence Isla Date: Wed, 20 Aug 2025 02:33:04 -0500 Subject: [PATCH] fix: logging the Haskell type instead of the listener error message directly Previously: Just "connection error..." Now: connection error... --- CHANGELOG.md | 1 + src/PostgREST/Observation.hs | 20 ++++++++++---------- test/io/test_io.py | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d3e392a8..6f0411acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix OpenAPI specification incorrectly exposing GET methods for volatile functions by @joelonsql in #4174 - Fix empty spread embeddings return unexpected SQL error by @taimoorzaeem in #3887 - Fix `/metrics` endpoint not responding with `Content-Type` header by @taimoorzaeem in #4271 +- Fix logging the Haskell type instead of the listener error message directly by @laurenceisla in #3588 ### Changed diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index 296de0f48..6e0b35516 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -110,11 +110,8 @@ observationMessage = \case DBListenStart channel -> do "Listening for database notifications on the " <> show channel <> " channel" DBListenFail channel listenErr -> - "Failed listening for database notifications on the " <> show channel <> " channel. " <> ( - case listenErr of - Left err -> show err - Right err -> showListenerError err - ) + "Failed listening for database notifications on the " <> show channel <> " channel. " <> + either showListenerConnError showListenerException listenErr DBListenRetry delay -> "Retrying listening for database notifications in " <> (show delay::Text) <> " seconds..." DBListenerGotSCacheMsg channel -> @@ -163,8 +160,11 @@ observationMessage = \case jsonMessage err = T.decodeUtf8 . LBS.toStrict . Error.errorPayload $ Error.PgError False err - showListenerError :: Either SomeException () -> Text - showListenerError (Right _) = "Failed getting notifications" -- should not happen as the listener will never finish (hasql-notifications uses `forever` internally) with a Right result - showListenerError (Left e) = - let showOnSingleLine txt = T.intercalate " " $ T.filter (/= '\t') <$> T.lines txt in -- the errors from hasql-notifications come intercalated with "\t\n" - showOnSingleLine $ show e + showOnSingleLine txt = T.intercalate " " $ T.filter (/= '\t') <$> T.lines txt -- the errors from hasql-notifications come intercalated with "\t\n" + + showListenerConnError :: SQL.ConnectionError -> Text + showListenerConnError = maybe "Connection error" (showOnSingleLine . T.decodeUtf8) + + showListenerException :: Either SomeException () -> Text + showListenerException (Right _) = "Failed getting notifications" -- should not happen as the listener will never finish (hasql-notifications uses `forever` internally) with a Right result + showListenerException (Left e) = showOnSingleLine $ show e diff --git a/test/io/test_io.py b/test/io/test_io.py index a2b1152f8..3c24c2256 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -1937,3 +1937,21 @@ def test_schema_cache_error_observation(defaultenv): "Failed to load the schema cache using db-schemas=public and db-extra-search-path=x" in output[7] ) + + +def test_log_listener_connection_errors(defaultenv): + "The logs should show the listener connection error message in a single line" + + env = { + **defaultenv, + "PGHOST": "no_host", + "PGRST_DB_CHANNEL_ENABLED": "true", + } + + with run(env=env, no_startup_stdout=False, wait_for_readiness=False) as postgrest: + output = postgrest.read_stdout(nlines=5) + assert any( + 'Failed listening for database notifications on the "pgrst" channel. could not translate host name "no_host" to address:' + in line + for line in output + )