diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e974e0b..7228e0afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. From versio ### Added - Log error when `db-schemas` config contains schema `pg_catalog` or `information_schema` by @taimoorzaeem in #4359 +- Add a `HINT` when the LISTEN channel stops working due to a PostgreSQL bug by @laurenceisla in #4581 ## [14.3] - 2026-01-03 diff --git a/src/PostgREST/Listener.hs b/src/PostgREST/Listener.hs index 0c5c42d4e..362a67eab 100644 --- a/src/PostgREST/Listener.hs +++ b/src/PostgREST/Listener.hs @@ -9,7 +9,8 @@ import qualified Hasql.Connection as SQL import qualified Hasql.Notifications as SQL import PostgREST.AppState (AppState, getConfig) import PostgREST.Config (AppConfig (..)) -import PostgREST.Observation (Observation (..)) +import PostgREST.Observation (Observation (..), + isDbListenerBug) import PostgREST.Version (prettyVersion) import qualified PostgREST.AppState as AppState @@ -33,6 +34,8 @@ retryingListen appState = do handleFinally err = do AppState.putIsListenerOn appState False observer $ DBListenFail dbChannel (Right err) + when (isDbListenerBug err) $ + observer DBListenBugHint unless configDbPoolAutomaticRecovery $ killThread mainThreadId diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index af7a6bca2..6c7a1cf64 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -12,6 +12,7 @@ module PostgREST.Observation , observationMessage , ObservationHandler , showOnSingleLine + , isDbListenerBug ) where import qualified Data.ByteString.Lazy as LBS @@ -46,6 +47,7 @@ data Observation | DBListenStart Text | DBListenFail Text (Either SQL.ConnectionError (Either SomeException ())) | DBListenRetry Int + | DBListenBugHint -- https://github.com/PostgREST/postgrest/issues/3147 | DBListenerGotSCacheMsg ByteString | DBListenerGotConfigMsg ByteString | QueryObs MainQuery Status @@ -114,6 +116,8 @@ observationMessage = \case either showListenerConnError showListenerException listenErr DBListenRetry delay -> "Retrying listening for database notifications in " <> (show delay::Text) <> " seconds..." + DBListenBugHint -> + "HINT: This is likely a bug in the notification queue, try executing the following to solve it: select pg_notification_queue_usage();" DBListenerGotSCacheMsg channel -> "Received a schema cache reload message on the " <> show channel <> " channel" DBListenerGotConfigMsg channel -> @@ -171,3 +175,7 @@ observationMessage = \case showOnSingleLine :: Char -> Text -> Text showOnSingleLine split txt = T.intercalate " " $ T.filter (/= split) <$> T.lines txt -- the errors from hasql-notifications come intercalated with "\t\n" + +isDbListenerBug :: Either SomeException () -> Bool +isDbListenerBug (Left e) = "could not access status of transaction" `T.isInfixOf` show e +isDbListenerBug _ = False