nu_protocol/errors/shell_error/
network.rs1use miette::{Diagnostic, LabeledSpan};
2use thiserror::Error;
3
4use crate::{ShellError, Span, Spanned};
5
6#[derive(Debug, Clone, PartialEq, Error, Diagnostic)]
7pub enum NetworkError {
8 #[error("Network failure")]
10 #[diagnostic(code(nu::shell::network))]
11 Generic {
12 msg: String,
13 #[label("{msg}")]
14 span: Span,
15 },
16
17 #[error(transparent)]
18 #[diagnostic(transparent)]
19 Dns(DnsError),
20 }
22
23#[derive(Debug, Clone, PartialEq, Error)]
24#[error("DNS Error")]
25pub struct DnsError {
26 pub kind: DnsErrorKind,
27 pub span: Span,
28 pub query: Spanned<String>,
29}
30
31impl Diagnostic for DnsError {
32 fn code<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {
33 self.kind.code()
34 }
35
36 fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
37 Some(Box::new(
38 [
39 LabeledSpan::new_with_span(Some("Could not be resolved".into()), self.query.span),
40 LabeledSpan::new_with_span(Some(self.kind.to_string()), self.span),
41 ]
42 .into_iter(),
43 ))
44 }
45
46 fn help<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {
47 Some(Box::new(format!("While querying \"{}\"", self.query)))
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Error, Diagnostic)]
52pub enum DnsErrorKind {
53 #[error("Temporary failure in name resolution")]
57 #[diagnostic(code(nu::shell::network::dns::again))]
58 Again,
59
60 #[error("Name or service is unknown")]
65 #[diagnostic(code(nu::shell::network::dns::no_name))]
66 NoName,
67
68 #[error("Host exists but has no address records")]
73 #[diagnostic(code(nu::shell::network::dns::no_data))]
74 NoData,
75
76 #[error("Non recoverable failure in name resolution")]
78 #[diagnostic(code(nu::shell::network::dns::fail))]
79 Fail,
80}
81
82impl From<DnsError> for ShellError {
83 fn from(value: DnsError) -> Self {
84 ShellError::Network(NetworkError::Dns(value))
85 }
86}