Tone down safekeeper and pageserver walreceiver errors (#3227)

Closes https://github.com/neondatabase/neon/issues/3114

Adds more typization into errors that appear during protocol messages (`FeMessage`), postgres and walreceiver connections.

Socket IO errors are now better detected and logged with lesser (INFO, DEBUG) error level, without traces that they were logged before, when they were wrapped in anyhow context.
This commit is contained in:
Kirill Bulatov
2023-01-03 22:42:04 +02:00
committed by GitHub
parent e9583db73b
commit 10dae79c6d
18 changed files with 635 additions and 334 deletions

View File

@@ -2,7 +2,7 @@ use crate::error::UserFacingError;
use anyhow::bail;
use bytes::BytesMut;
use pin_project_lite::pin_project;
use pq_proto::{BeMessage, FeMessage, FeStartupPacket};
use pq_proto::{BeMessage, ConnectionError, FeMessage, FeStartupPacket};
use rustls::ServerConfig;
use std::pin::Pin;
use std::sync::Arc;
@@ -47,18 +47,13 @@ fn err_connection() -> io::Error {
io::Error::new(io::ErrorKind::ConnectionAborted, "connection is lost")
}
// TODO: change error type of `FeMessage::read_fut`
fn from_anyhow(e: anyhow::Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, e.to_string())
}
impl<S: AsyncRead + Unpin> PqStream<S> {
/// Receive [`FeStartupPacket`], which is a first packet sent by a client.
pub async fn read_startup_packet(&mut self) -> io::Result<FeStartupPacket> {
// TODO: `FeStartupPacket::read_fut` should return `FeStartupPacket`
let msg = FeStartupPacket::read_fut(&mut self.stream)
.await
.map_err(from_anyhow)?
.map_err(ConnectionError::into_io_error)?
.ok_or_else(err_connection)?;
match msg {
@@ -80,7 +75,7 @@ impl<S: AsyncRead + Unpin> PqStream<S> {
async fn read_message(&mut self) -> io::Result<FeMessage> {
FeMessage::read_fut(&mut self.stream)
.await
.map_err(from_anyhow)?
.map_err(ConnectionError::into_io_error)?
.ok_or_else(err_connection)
}
}
@@ -112,7 +107,8 @@ impl<S: AsyncWrite + Unpin> PqStream<S> {
/// This method exists due to `&str` not implementing `Into<anyhow::Error>`.
pub async fn throw_error_str<T>(&mut self, error: &'static str) -> anyhow::Result<T> {
tracing::info!("forwarding error to user: {error}");
self.write_message(&BeMessage::ErrorResponse(error)).await?;
self.write_message(&BeMessage::ErrorResponse(error, None))
.await?;
bail!(error)
}
@@ -124,7 +120,8 @@ impl<S: AsyncWrite + Unpin> PqStream<S> {
{
let msg = error.to_string_client();
tracing::info!("forwarding error to user: {msg}");
self.write_message(&BeMessage::ErrorResponse(&msg)).await?;
self.write_message(&BeMessage::ErrorResponse(&msg, None))
.await?;
bail!(error)
}
}