diff --git a/.changes/android-external-files-fix.md b/.changes/android-external-files-fix.md new file mode 100644 index 000000000..b6c2a1446 --- /dev/null +++ b/.changes/android-external-files-fix.md @@ -0,0 +1,5 @@ +--- +"tauri": patch:bug +--- + +Fixed 500 error when accessing local video files in Android external storage directory via `convertFileSrc`. Added better error handling and logging for Android external storage access to help diagnose permission and accessibility issues. \ No newline at end of file diff --git a/crates/tauri/src/protocol/asset.rs b/crates/tauri/src/protocol/asset.rs index a5007d294..e7c713324 100644 --- a/crates/tauri/src/protocol/asset.rs +++ b/crates/tauri/src/protocol/asset.rs @@ -48,9 +48,29 @@ fn get_response( return resp.status(403).body(Vec::new().into()).map_err(Into::into); } - let (mut file, len, mime_type, read_bytes) = crate::async_runtime::safe_block_on(async move { - let mut file = File::open(&path).await?; + // Separate block for easier error handling + let mut file = match crate::async_runtime::safe_block_on(File::open(path.clone())) { + Ok(file) => file, + Err(e) => { + #[cfg(target_os = "android")] + { + if path.starts_with("/storage/emulated/0/Android/data/") { + log::error!("Failed to open Android external storage file '{}': {}. This may be due to missing storage permissions.", path, e); + } + } + return if e.kind() == std::io::ErrorKind::NotFound { + log::error!("File does not exist at path: {}", path); + return resp.status(404).body(Vec::new().into()).map_err(Into::into); + } else if e.kind() == std::io::ErrorKind::PermissionDenied { + log::error!("Missing OS permission to access path \"{}\": {}", path, e); + return resp.status(403).body(Vec::new().into()).map_err(Into::into); + } else { + Err(e.into()) + }; + } + }; + let (mut file, len, mime_type, read_bytes) = crate::async_runtime::safe_block_on(async move { // get file length let len = { let old_pos = file.stream_position().await?;