Skip to main content

google_cloud_pubsub/
error.rs

1// Copyright 2026 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Custom errors for the Cloud Pub/Sub clients.
16
17use crate::Error;
18use std::sync::Arc;
19
20/// Represents an error that can occur when publishing a message.
21#[derive(thiserror::Error, Debug)]
22#[non_exhaustive]
23pub enum PublishError {
24    /// The underlying RPC failed.
25    ///
26    /// The inner error is wrapped in an [`Arc`] because the same error may
27    /// affect multiple [`publish()`](crate::client::Publisher::publish) calls.
28    #[error("the publish operation was interrupted by an error: {0}")]
29    Rpc(#[source] Arc<Error>),
30
31    /// Publishing is paused because a previous message with the same ordering key failed.
32    ///
33    /// To prevent messages from being sent out of order, the [`Publisher`](crate::client::Publisher)
34    /// paused messages for the ordering key.
35    ///
36    /// To resume publishing, call [`Publisher::resume_publish`](crate::client::Publisher::resume_publish).
37    #[error("publishing is paused for the ordering key")]
38    OrderingKeyPaused,
39
40    /// The operation failed because the [`Publisher`](crate::client::Publisher) has
41    /// been shut down.
42    ///
43    /// Typically this can happen when the application is shutting down. Some background
44    /// tasks in the client library may be terminated before they can send all the
45    /// pending messages.
46    #[error("the publisher has shut down")]
47    Shutdown,
48}
49
50/// Represents an error that can occur when acking or nacking a message.
51#[derive(thiserror::Error, Debug)]
52#[non_exhaustive]
53pub enum AckError {
54    /// The message's lease expired before the client could ack or nack it.
55    ///
56    /// The message has not been acked, and will be redelivered, maybe to
57    /// another client.
58    #[error("the message's lease has already expired. It was not acked, and will be redelivered.")]
59    LeaseExpired,
60
61    /// The underlying RPC failed.
62    #[non_exhaustive]
63    #[error("the operation failed. RPC error: {source}")]
64    Rpc {
65        /// The error returned by the service for the request.
66        #[source]
67        source: Arc<Error>,
68    },
69
70    /// Lease management shutdown before the client could acknowledge the
71    /// message.
72    ///
73    /// The client did not acknowledge the message. The service will redeliver
74    /// message.
75    #[error(
76        "shutdown before attempting the operation. \
77         The message was not acknowledged, and will be redelivered."
78    )]
79    ShutdownBeforeAck,
80
81    /// Error during shutdown.
82    ///
83    /// The result of the operation is unknown. If you attempted to ack
84    /// the message, the service may or may not redeliver it.
85    #[error("error during shutdown. The result of the operation is unknown. {0}")]
86    Shutdown(#[source] Box<dyn std::error::Error + Send + Sync + 'static>),
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92    use google_cloud_gax::error::rpc::{Code, Status};
93
94    #[test]
95    fn ack_error_rpc_debug() {
96        let e = AckError::Rpc {
97            source: Arc::new(Error::service(
98                Status::default()
99                    .set_code(Code::FailedPrecondition)
100                    .set_message("inner fail"),
101            )),
102        };
103        let fmt = format!("{e}");
104        assert!(fmt.contains("operation failed."), "{fmt}");
105        assert!(fmt.contains("inner fail"), "{fmt}");
106    }
107}