Universal-Debloater-Alliance/universal-android-debloater-next-generation · critical
setup logging
Error message
setup logging
What it means
main calls setup_logger().expect("setup logging"), which creates and locks a log file (CACHE_DIR/uadng.log) and attaches the terminal on Windows. If logger initialization fails (cache dir unresolvable/unwritable, log file can't be created), the app panics before launching the GUI, so the user sees a panic message instead of the application.
Solutions
- Ensure the cache directory exists and is writable (check `ls -ld ~/.cache`, free disk space) before launching.
- Replace .expect with a graceful path: fall back to logging to stderr/no-op logger so the GUI still starts.
- In sandboxed installs, redirect the log dir to a writable location (XDG_CACHE_HOME) via the launcher wrapper.
- Close the other running instance that may hold the log file lock, or use a rotating/unique log filename.
Example fix
// before
setup_logger().expect("setup logging");
UadGui::start()
// after
if let Err(e) = setup_logger() {
eprintln!("Logging disabled: {e}");
}
UadGui::start() Defensive patterns
Strategy: try-catch
Validate before calling
if !cache_dir.exists() || std::fs::OpenOptions::new().write(true).create_new(cache_dir.join(".probe")).is_err() {
eprintln!("cache dir not writable; logging will be degraded");
} Try / catch
if let Err(e) = setup_logger() {
eprintln!("failed to init logging: {e}; continuing without file logging");
} Prevention
- Never let logging initialization be fatal — degrade to stderr instead.
- Check disk space and write permissions on the cache dir before first launch.
- Avoid two instances contending for the same log file; use unique or rotating filenames.
When it happens
Trigger: Running the binary when CACHE_DIR is unwritable or missing (read-only home, disk full, sandboxed launch without filesystem access), or on Windows when attaching the terminal/console fails; also triggered indirectly when error 16's CACHE_DIR was computed but the directory couldn't be created inside setup_logger.
Common situations: Flatpak/snap or portable installs with read-only cache paths; running under a service account whose cache dir isn't writable; antivirus blocking creation of uadng.log on Windows; two instances racing to lock the same log file.
Related errors
- {e}
- Could not write config file to disk!
- Unable to write file
- Can't detect cache dir
- There must be 1 tab after serial
AI-assisted analysis of Universal-Debloater-Alliance/universal-android-debloater-next-generation@64465c850c (2026-09-12).
Data as JSON: /api/errors/5cabe8afd462b36a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/uad-gui/src/main.rs:27
use std::{fmt::Arguments, fs::OpenOptions, path::PathBuf};
use uad_core::utils::setup_uad_dir;
use uad_gui::gui::UadGui;
static CACHE_DIR: LazyLock<PathBuf> =
LazyLock::new(|| setup_uad_dir(&dirs::cache_dir().expect("Can't detect cache dir")));
fn main() -> iced::Result {
// Safety: This function is safe to call in a single-threaded program.
// The exact requirement is: you must ensure that there are no other threads concurrently writing or
// reading(!) the environment through functions or global variables other than the ones in this module.
unsafe {
// Force WGPU/Iced to use discrete GPU to prevent crashes on PCs with two GPUs.
// See #848 and related pull 850.
std::env::set_var("WGPU_POWER_PREF", "high");
}
setup_logger().expect("setup logging");
UadGui::start()
}
/// Sets up logging to a new file in `CACHE_DIR"/uadng.log"`
/// Also attaches the terminal on Windows machines
/// '''
/// match `setup_logger().expect("Error` setting up logger")
/// '''
fn setup_logger() -> Result<(), fern::InitError> {
#[cfg(target_os = "windows")]
{
attach_windows_console();
}
let colors = ColoredLevelConfig::new().info(Color::Green);
let make_formatter = |use_colors: bool| {
move |out: FormatCallback, message: &Arguments, record: &Record| {View on GitHub (pinned to 64465c850c)