diff --git a/src/environmentd/tests/server.rs b/src/environmentd/tests/server.rs index 7f52d939975bd..93152114fe802 100644 --- a/src/environmentd/tests/server.rs +++ b/src/environmentd/tests/server.rs @@ -1542,8 +1542,8 @@ fn test_max_request_size() { let param = std::iter::repeat("1").take(param_size).join(""); let mut client = server.connect(postgres::NoTls).unwrap(); - // The specific error isn't forwarded to the client, the connection is just closed. - assert!(client.query(statement, &[¶m]).is_err()); + let err = client.query(statement, &[¶m]).unwrap_db_error(); + assert_contains!(err.message(), "request larger than"); assert!(client.is_valid(Duration::from_secs(2)).is_err()); } diff --git a/src/pgwire/src/protocol.rs b/src/pgwire/src/protocol.rs index 671bdb23383c1..f0bc48f8ca673 100644 --- a/src/pgwire/src/protocol.rs +++ b/src/pgwire/src/protocol.rs @@ -324,7 +324,22 @@ where }; select! { - r = machine.run() => r, + r = machine.run() => { + // Errors produced internally (like MAX_REQUEST_SIZE being exceeded) should send an + // error to the client informing them why the connection was closed. We still want to + // return the original error up the stack, though, so we skip error checking during conn + // operations. + if let Err(err) = &r { + let _ = conn + .send(ErrorResponse::fatal( + SqlState::CONNECTION_FAILURE, + err.to_string(), + )) + .await; + let _ = conn.flush().await; + } + r + }, _ = is_expired => { conn .send(ErrorResponse::fatal(SqlState::INVALID_AUTHORIZATION_SPECIFICATION, "authentication expired"))