Skip to main content

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("Packet size ({}) exceeds the negotiated maximum ({})", .size, .max)]
41    PacketTooLarge { size: usize, max: usize },
42    #[error(transparent)]
43    Other(#[from] anyhow::Error),
44}
45
46impl Error {
47    pub fn peer_rejected(operation: OpCode, response: ResponseCode) -> Self {
48        Self::PeerRejected { operation, response }
49    }
50
51    pub fn response(operation: OpCode, msg: impl Into<String>) -> Self {
52        Self::PeerResponse { operation, msg: msg.into() }
53    }
54
55    pub fn operation(operation: OpCode, msg: impl Into<String>) -> Self {
56        Self::OperationError { operation, msg: msg.into() }
57    }
58
59    pub fn not_implemented(operation: OpCode) -> Self {
60        Self::NotImplemented { operation }
61    }
62
63    pub fn packet_too_large(size: usize, max: usize) -> Self {
64        Self::PacketTooLarge { size, max }
65    }
66
67    pub fn other(msg: impl Into<String>) -> Self {
68        Self::Other(format_err!(msg.into()).into())
69    }
70}
71
72/// Errors that occur during the encoding & decoding of OBEX packets.
73#[derive(Error, Debug)]
74pub enum PacketError {
75    #[error("Buffer is too small")]
76    BufferTooSmall,
77    #[error("Invalid data length")]
78    DataLength,
79    #[error("Invalid data: {}", .0)]
80    Data(String),
81    #[error("Invalid header identifier: {}", .0)]
82    Identifier(u8),
83    #[error("Invalid packet OpCode: {}", .0)]
84    OpCode(u8),
85    #[error("Invalid header encoding")]
86    HeaderEncoding,
87    #[error("Invalid response code: {}", .0)]
88    ResponseCode(u8),
89    #[error("Field is RFA.")]
90    Reserved,
91    /// An error from another source
92    #[error(transparent)]
93    Other(#[from] anyhow::Error),
94}
95
96impl PacketError {
97    pub fn external(e: impl Into<anyhow::Error>) -> Self {
98        Self::Other(e.into())
99    }
100
101    pub fn data(e: impl Into<String>) -> Self {
102        Self::Data(e.into())
103    }
104}