Skip to main content

Mountain/IPC/WindServiceHandlers/FileSystem/Native/
FileStatNative.rs

1//! Wire method `file:stat`. Returns VS Code's `IStat` shape via
2//! `metadata_to_istat`. Uses `symlink_metadata` to avoid following
3//! symlinks (matches Electron behaviour). Noise from benign ENOENTs on
4//! known VS Code probe paths is squelched via `IsBenignEnoent` +
5//! `DebugOnce`.
6
7use serde_json::Value;
8
9use crate::{
10	IPC::{
11		DevLog,
12		WindServiceHandlers::Utilities::{
13			MetadataEncoding::Fn as metadata_to_istat,
14			PathExtraction::Fn as extract_path_from_arg,
15		},
16	},
17	dev_log,
18};
19
20pub async fn Fn(Arguments:Vec<Value>) -> Result<Value, String> {
21	let Path = extract_path_from_arg(Arguments.get(0).ok_or("Missing file path")?)?;
22
23	// Per-path stat emits at very high volume during workbench boot
24	// (package.json / launch.json / settings.json probes from every
25	// extension). Gate to `vfs-verbose`; the ENOENT path retains the
26	// `vfs` tag so real misses still surface at the default level.
27	if !DevLog::IsBenignEnoent::Fn(&Path) {
28		dev_log!("vfs-verbose", "stat: {}", Path);
29	}
30
31	let Metadata = tokio::fs::symlink_metadata(&Path).await.map_err(|E| {
32		if DevLog::IsBenignEnoent::Fn(&Path) {
33			DevLog::DebugOnce::Fn(
34				"vfs",
35				&format!("stat-enoent:{}", Path),
36				&format!("stat ENOENT (benign): {}", Path),
37			);
38		} else {
39			dev_log!("vfs", "stat ENOENT: {}", Path);
40		}
41
42		// Suffix "resource not found" on ENOENT so Wind's file-system
43		// error classifier maps this to FileSystemError.FileNotFound
44		// rather than FileSystemError.Unknown.
45		if E.kind() == std::io::ErrorKind::NotFound {
46			format!("stat: {} resource not found (path: {})", E, Path)
47		} else {
48			format!("Failed to stat file: {} (path: {})", E, Path)
49		}
50	})?;
51
52	if !DevLog::IsBenignEnoent::Fn(&Path) {
53		dev_log!("vfs-verbose", "stat OK: {} (dir={})", Path, Metadata.is_dir());
54	}
55
56	Ok(metadata_to_istat(&Metadata))
57}