trust_dns_server/authority/
error.rs

1// Copyright 2015-2019 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use std::io;
9
10use enum_as_inner::EnumAsInner;
11use thiserror::Error;
12
13use crate::proto::op::ResponseCode;
14#[cfg(feature = "trust-dns-resolver")]
15use crate::resolver::error::ResolveError;
16
17// TODO: should this implement Failure?
18#[allow(clippy::large_enum_variant)]
19/// A query could not be fulfilled
20#[derive(Debug, EnumAsInner, Error)]
21#[non_exhaustive]
22pub enum LookupError {
23    /// A record at the same Name as the query exists, but not of the queried RecordType
24    #[error("The name exists, but not for the record requested")]
25    NameExists,
26    /// There was an error performing the lookup
27    #[error("Error performing lookup: {0}")]
28    ResponseCode(ResponseCode),
29    /// Resolve Error
30    #[cfg(feature = "trust-dns-resolver")]
31    #[cfg_attr(docsrs, doc(cfg(feature = "resolver")))]
32    #[error("Forward resolution error: {0}")]
33    ResolveError(#[from] ResolveError),
34    /// Recursive Resolver Error
35    #[cfg(feature = "trust-dns-recursor")]
36    #[cfg_attr(docsrs, doc(cfg(feature = "recursor")))]
37    #[error("Recursive resolution error: {0}")]
38    RecursiveError(#[from] trust_dns_recursor::Error),
39    /// An underlying IO error occurred
40    #[error("io error: {0}")]
41    Io(io::Error),
42}
43
44impl LookupError {
45    /// Create a lookup error, specifying that a name exists at the location, but no matching RecordType
46    pub fn for_name_exists() -> Self {
47        Self::NameExists
48    }
49
50    /// This is a non-existent domain name
51    pub fn is_nx_domain(&self) -> bool {
52        matches!(*self, Self::ResponseCode(ResponseCode::NXDomain))
53    }
54
55    /// This is a non-existent domain name
56    pub fn is_refused(&self) -> bool {
57        matches!(*self, Self::ResponseCode(ResponseCode::Refused))
58    }
59}
60
61impl From<ResponseCode> for LookupError {
62    fn from(code: ResponseCode) -> Self {
63        // this should never be a NoError
64        debug_assert!(code != ResponseCode::NoError);
65        Self::ResponseCode(code)
66    }
67}
68
69impl From<io::Error> for LookupError {
70    fn from(e: io::Error) -> Self {
71        Self::Io(e)
72    }
73}
74
75impl From<LookupError> for io::Error {
76    fn from(e: LookupError) -> Self {
77        Self::new(io::ErrorKind::Other, Box::new(e))
78    }
79}
80
81/// Result of a Lookup in the Catalog and Authority
82pub type LookupResult<T> = Result<T, LookupError>;