zero_postgres/protocol/backend/
error.rs

1//! Error and notice response messages.
2
3use std::collections::HashMap;
4
5use crate::error::{Error, Result, ServerError};
6use crate::protocol::codec::read_cstr;
7
8/// Parse error/notice fields from payload into a ServerError.
9fn parse_fields(payload: &[u8]) -> Result<ServerError> {
10    let mut fields = HashMap::new();
11    let mut data = payload;
12
13    while !data.is_empty() && data[0] != 0 {
14        let field_type = data[0];
15        data = &data[1..];
16
17        let (value, rest) = read_cstr(data)?;
18        data = rest;
19
20        fields.insert(field_type, value.to_string());
21    }
22
23    Ok(ServerError::new(fields))
24}
25
26/// ErrorResponse message - fatal error from server.
27#[derive(Debug, Clone)]
28pub struct ErrorResponse(pub ServerError);
29
30impl ErrorResponse {
31    /// Parse an ErrorResponse message from payload bytes.
32    pub fn parse(payload: &[u8]) -> Result<Self> {
33        Ok(Self(parse_fields(payload)?))
34    }
35
36    /// Convert to an Error.
37    pub fn into_error(self) -> Error {
38        Error::Server(self.0)
39    }
40
41    /// Get the underlying ServerError.
42    pub fn error(&self) -> &ServerError {
43        &self.0
44    }
45}
46
47/// NoticeResponse message - non-fatal warning/info from server.
48#[derive(Debug, Clone)]
49pub struct NoticeResponse(pub ServerError);
50
51impl NoticeResponse {
52    /// Parse a NoticeResponse message from payload bytes.
53    pub fn parse(payload: &[u8]) -> Result<Self> {
54        Ok(Self(parse_fields(payload)?))
55    }
56
57    /// Get the underlying ServerError.
58    pub fn error(&self) -> &ServerError {
59        &self.0
60    }
61}