From a6b324678293d65f3a417b8f66889b3f3f6a9c29 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Mon, 26 Jan 2026 10:04:44 +0100
Subject: [PATCH v1 4/5] perl tap: Include caller in die messages of psql

This way by looking at the error output you can actually figure out
where it occured, instead of just knowing that is in the very often
called psql function.

Output of a failed safe_psql call now looks like this:

die: error running SQL at /home/jelte/work/postgres-3/src/test/authentication/t/001_password.pl line 144: 'psql:<stdin>:2: ERROR:  unterminated quoted string at or near "'"
LINE 1: GRANT ALL ON sysuser_data TO scram_role '
                                                ^'
while running 'psql --no-psqlrc --no-align --tuples-only --quiet --dbname port=15305 host=/tmp/lhu1ix_Wgj dbname='postgres' --file - --variable ON_ERROR_STOP=1' with sql 'CREATE TABLE sysuser_data (n) AS SELECT NULL FROM generate_series(1, 10);
   GRANT ALL ON sysuser_data TO scram_role '' at /home/jelte/work/postgres-3/src/test/perl/PostgreSQL/Test/Cluster.pm line 2305.
Tests were run but no plan was declared and done_testing() was not seen.
Looks like your test exited with 29 just after 21.
---
 src/test/perl/PostgreSQL/Test/Cluster.pm | 25 ++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index e267ba868fe..68bdff2ad4e 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -2042,7 +2042,8 @@ sub safe_psql
 		stdout => \$stdout,
 		stderr => \$stderr,
 		on_error_die => 1,
-		on_error_stop => 1);
+		on_error_stop => 1,
+		caller => [caller]);
 
 	# psql can emit stderr from NOTICEs etc
 	if ($stderr ne "")
@@ -2213,6 +2214,8 @@ sub psql
 	$$stderr = "" if ref($stderr);
 
 	my $ret;
+	my @caller = defined $params{caller} ? @{ $params{caller} } : caller;
+	my $caller_location = "at $caller[1] line $caller[2]";
 
 	# Run psql and capture any possible exceptions.  If the exception is
 	# because of a timeout and the caller requested to handle that, just return
@@ -2261,7 +2264,7 @@ sub psql
 			}
 			else
 			{
-				die "psql timed out: stderr: '$$stderr'\n"
+				die "psql timed out $caller_location: stderr: '$$stderr'\n"
 				  . "while running '@psql_params'";
 			}
 		}
@@ -2284,23 +2287,25 @@ sub psql
 	if (defined $ret)
 	{
 		my $core = $ret & 128 ? " (core dumped)" : "";
-		die "psql exited with signal "
-		  . ($ret & 127)
-		  . "$core: '$$stderr' while running '@psql_params'"
-		  if $ret & 127;
+		if ($ret & 127)
+		{
+			die "psql exited with signal "
+			  . ($ret & 127)
+			  . "$core $caller_location: '$$stderr' while running '@psql_params'";
+		}
 		$ret = $ret >> 8;
 	}
 
 	if ($ret && $params{on_error_die})
 	{
-		die "psql error: stderr: '$$stderr'\nwhile running '@psql_params'"
+		die "psql error $caller_location: stderr: '$$stderr'\nwhile running '@psql_params'"
 		  if $ret == 1;
-		die "connection error: '$$stderr'\nwhile running '@psql_params'"
+		die "connection error $caller_location: '$$stderr'\nwhile running '@psql_params'"
 		  if $ret == 2;
 		die
-		  "error running SQL: '$$stderr'\nwhile running '@psql_params' with sql '$sql'"
+		  "error running SQL $caller_location: '$$stderr'\nwhile running '@psql_params' with sql '$sql'"
 		  if $ret == 3;
-		die "psql returns $ret: '$$stderr'\nwhile running '@psql_params'";
+		die "psql returns $ret $caller_location: '$$stderr'\nwhile running '@psql_params'";
 	}
 
 	if (wantarray)
-- 
2.52.0

