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

  1. Ensure the cache directory exists and is writable (check `ls -ld ~/.cache`, free disk space) before launching.
  2. Replace .expect with a graceful path: fall back to logging to stderr/no-op logger so the GUI still starts.
  3. In sandboxed installs, redirect the log dir to a writable location (XDG_CACHE_HOME) via the launcher wrapper.
  4. 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

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


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)