bt_obex/
error.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::format_err;
6
7use objects::ObexObjectError;
8use thiserror::Error;
9
10use crate::header::HeaderIdentifier;
11use crate::operation::{OpCode, ResponseCode};
12
13/// Errors that occur during the use of the OBEX library.
14#[derive(Error, Debug)]
15pub enum Error {
16    #[error("Error parsing packet: {:?}", .0)]
17    Packet(#[from] PacketError),
18    #[error("Header {:?} already exists in HeaderSet", .0)]
19    AlreadyExists(HeaderIdentifier),
20    #[error("{:?} cannot be added with {:?}", .0, .1)]
21    IncompatibleHeaders(HeaderIdentifier, HeaderIdentifier),
22    #[error("Encountered an IO Error: {}", .0)]
23    IOError(#[from] zx::Status),
24    #[error("Invalid OBEX object: {:?}", .0)]
25    Object(#[from] ObexObjectError),
26    #[error("Operation is already in progress")]
27    OperationInProgress,
28    #[error("Internal error during {:?}: {:?}", .operation, .msg)]
29    OperationError { operation: OpCode, msg: String },
30    #[error("Single Response Mode is not supported")]
31    SrmNotSupported,
32    #[error("Peer disconnected")]
33    PeerDisconnected,
34    #[error("Peer rejected {:?} request with Error: {:?}", .operation, .response)]
35    PeerRejected { operation: OpCode, response: ResponseCode },
36    #[error("Invalid {:?} response from peer: {:?}", .operation, .msg)]
37    PeerResponse { operation: OpCode, msg: String },
38    #[error("{:?} is not implemented", .operation)]
39    NotImplemented { operation: OpCode },
40    #[error(transparent)]
41    Other(#[from] anyhow::Error),
42}
43
44impl Error {
45    pub fn peer_rejected(operation: OpCode, response: ResponseCode) -> Self {
46        Self::PeerRejected { operation, response }
47    }
48
49    pub fn response(operation: OpCode, msg: impl Into<String>) -> Self {
50        Self::PeerResponse { operation, msg: msg.into() }
51    }
52
53    pub fn operation(operation: OpCode, msg: impl Into<String>) -> Self {
54        Self::OperationError { operation, msg: msg.into() }
55    }
56
57    pub fn not_implemented(operation: OpCode) -> Self {
58        Self::NotImplemented { operation }
59    }
60
61    pub fn other(msg: impl Into<String>) -> Self {
62        Self::Other(format_err!(msg.into()).into())
63    }
64}
65
66/// Errors that occur during the encoding & decoding of OBEX packets.
67#[derive(Error, Debug)]
68pub enum PacketError {
69    #[error("Buffer is too small")]
70    BufferTooSmall,
71    #[error("Invalid data length")]
72    DataLength,
73    #[error("Invalid data: {}", .0)]
74    Data(String),
75    #[error("Invalid header identifier: {}", .0)]
76    Identifier(u8),
77    #[error("Invalid packet OpCode: {}", .0)]
78    OpCode(u8),
79    #[error("Invalid header encoding")]
80    HeaderEncoding,
81    #[error("Invalid response code: {}", .0)]
82    ResponseCode(u8),
83    #[error("Field is RFA.")]
84    Reserved,
85    /// An error from another source
86    #[error(transparent)]
87    Other(#[from] anyhow::Error),
88}
89
90impl PacketError {
91    pub fn external(e: impl Into<anyhow::Error>) -> Self {
92        Self::Other(e.into())
93    }
94
95    pub fn data(e: impl Into<String>) -> Self {
96        Self::Data(e.into())
97    }
98}