parcel_resolver/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use crate::specifier::SpecifierError;
use crate::PackageJsonError;
use std::path::PathBuf;
use std::sync::Arc;

/// An error that occcured during resolution.
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
#[serde(tag = "type")]
pub enum ResolverError {
  /// An unknown URL scheme was found in the specifier.
  UnknownScheme { scheme: String },
  /// An unknown error occurred.
  UnknownError,
  /// A file was not found.
  FileNotFound { relative: PathBuf, from: PathBuf },
  /// A node_modules directory was not found.
  ModuleNotFound { module: String },
  /// A package.json entry field pointed to a non-existent file.
  ModuleEntryNotFound {
    /// The node_modules package name.
    module: String,
    /// Path of the entry found in package.json.
    entry_path: PathBuf,
    /// Path of the package.json.
    package_path: PathBuf,
    /// Package.json field name.
    field: &'static str,
  },
  /// A sub-path could not be found within a node_modules package.
  ModuleSubpathNotFound {
    /// The node_modules package name.
    module: String,
    /// Path of the non-existent file.
    path: PathBuf,
    /// Path of the package.json.
    package_path: PathBuf,
  },
  /// An error parsing JSON.
  JsonError(JsonError),
  /// An I/O error.
  IOError(IOError),
  /// A sub-path was not exported from a package.json.
  PackageJsonError {
    /// The node_modules package name.
    module: String,
    /// The path of the file that is not exported.
    path: PathBuf,
    /// Reason the path was not exported.
    error: PackageJsonError,
  },
  /// A package.json file could not be found above the given path.
  PackageJsonNotFound { from: PathBuf },
  /// Could not parse the specifier.
  InvalidSpecifier(SpecifierError),
  /// Could not find an extended tsconfig.json file.
  TsConfigExtendsNotFound {
    /// Path of the tsconfig.json with the "extends" field.
    tsconfig: PathBuf,
    /// Original error resolving the tsconfig.json extends specifier.
    error: Box<ResolverError>,
  },
}

/// An error parsing JSON.
#[derive(Debug, Clone, PartialEq, serde::Serialize)]
pub struct JsonError {
  /// Path of the JSON file.
  pub path: PathBuf,
  /// Line number of the error.
  pub line: usize,
  /// Column number of the error.
  pub column: usize,
  /// Reason for the error.
  pub message: String,
}

impl JsonError {
  pub fn new(path: PathBuf, err: serde_json::Error) -> JsonError {
    JsonError {
      path,
      line: err.line(),
      column: err.column(),
      message: err.to_string(),
    }
  }
}

#[derive(Debug, Clone)]
pub struct IOError(Arc<std::io::Error>);

impl serde::Serialize for IOError {
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  where
    S: serde::Serializer,
  {
    #[derive(serde::Serialize)]
    struct IOErrorMessage {
      message: String,
    }

    let msg = IOErrorMessage {
      message: self.0.to_string(),
    };

    msg.serialize(serializer)
  }
}

impl PartialEq for IOError {
  fn eq(&self, other: &Self) -> bool {
    self.0.kind() == other.0.kind()
  }
}

impl From<()> for ResolverError {
  fn from(_: ()) -> Self {
    ResolverError::UnknownError
  }
}

impl From<std::str::Utf8Error> for ResolverError {
  fn from(_: std::str::Utf8Error) -> Self {
    ResolverError::UnknownError
  }
}

impl From<JsonError> for ResolverError {
  fn from(e: JsonError) -> Self {
    ResolverError::JsonError(e)
  }
}

impl From<std::io::Error> for ResolverError {
  fn from(e: std::io::Error) -> Self {
    ResolverError::IOError(IOError(Arc::new(e)))
  }
}

impl From<SpecifierError> for ResolverError {
  fn from(value: SpecifierError) -> Self {
    ResolverError::InvalidSpecifier(value)
  }
}

impl std::fmt::Display for ResolverError {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(f, "{:?}", self)
  }
}

impl std::error::Error for ResolverError {}