1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 16:49:41 +00:00

fix: implement layered error tolerance and accurate cleanup reporting (#175 #176 #180)

- Fix safe_remove set -e trap in command substitution
  - Fix has_full_disk_access false positives and unknown state handling
  - Use set +e in perform_cleanup for graceful degradation
  - Track removal failures and only count actually deleted items (#180)
  - Add "Skipped X items (permission denied or in use)" notification
  - Improve spinner reliability with cooperative stop mechanism (#175)
This commit is contained in:
Tw93
2025-12-29 14:27:47 +08:00
parent 16de9d13a8
commit 694c55f73b
15 changed files with 228 additions and 546 deletions

View File

@@ -125,16 +125,12 @@ cleanup() {
fi
CLEANUP_DONE=true
# Stop all spinners and clear the line
if [[ -n "${INLINE_SPINNER_PID:-}" ]] && kill -0 "$INLINE_SPINNER_PID" 2> /dev/null; then
kill "$INLINE_SPINNER_PID" 2> /dev/null || true
wait "$INLINE_SPINNER_PID" 2> /dev/null || true
INLINE_SPINNER_PID=""
fi
# Stop any inline spinner
stop_inline_spinner 2> /dev/null || true
# Clear any spinner output - spinner outputs to stderr
if [[ -t 1 ]]; then
printf "\r\033[K" >&2
printf "\r\033[K" >&2 || true
fi
# Clean up temporary files
@@ -205,6 +201,8 @@ safe_clean() {
local total_size_bytes=0
local total_count=0
local skipped_count=0
local removal_failed_count=0
local permission_start=${MOLE_PERMISSION_DENIED_COUNT:-0}
local show_scan_feedback=false
if [[ ${#targets[@]} -gt 20 && -t 1 ]]; then
@@ -316,17 +314,25 @@ safe_clean() {
if [[ -f "$result_file" ]]; then
read -r size count < "$result_file" 2> /dev/null || true
if [[ "$count" -gt 0 && "$size" -gt 0 ]]; then
local removed=1
if [[ "$DRY_RUN" != "true" ]]; then
removed=0
# Handle symbolic links separately (only remove the link, not the target)
if [[ -L "$path" ]]; then
rm "$path" 2> /dev/null || true
rm "$path" 2> /dev/null && removed=1
else
safe_remove "$path" true || true
if safe_remove "$path" true; then
removed=1
fi
fi
fi
((total_size_bytes += size))
((total_count += 1))
removed_any=1
if [[ $removed -eq 1 ]]; then
((total_size_bytes += size))
((total_count += 1))
removed_any=1
else
((removal_failed_count++))
fi
fi
fi
((idx++))
@@ -341,17 +347,25 @@ safe_clean() {
# Optimization: Skip expensive file counting
if [[ "$size_bytes" -gt 0 ]]; then
local removed=1
if [[ "$DRY_RUN" != "true" ]]; then
removed=0
# Handle symbolic links separately (only remove the link, not the target)
if [[ -L "$path" ]]; then
rm "$path" 2> /dev/null || true
rm "$path" 2> /dev/null && removed=1
else
safe_remove "$path" true || true
if safe_remove "$path" true; then
removed=1
fi
fi
fi
((total_size_bytes += size_bytes))
((total_count += 1))
removed_any=1
if [[ $removed -eq 1 ]]; then
((total_size_bytes += size_bytes))
((total_count += 1))
removed_any=1
else
((removal_failed_count++))
fi
fi
((idx++))
done
@@ -361,6 +375,16 @@ safe_clean() {
stop_section_spinner
fi
# Track permission failures reported by safe_remove
local permission_end=${MOLE_PERMISSION_DENIED_COUNT:-0}
if [[ $permission_end -gt $permission_start && $removed_any -eq 0 ]]; then
debug_log "Permission denied while cleaning: $description"
fi
if [[ $removal_failed_count -gt 0 && "$DRY_RUN" != "true" ]]; then
echo -e " ${YELLOW}${ICON_WARNING}${NC} Skipped $removal_failed_count items (permission denied or in use)"
note_activity
fi
if [[ $removed_any -eq 1 ]]; then
local size_human=$(bytes_to_human "$((total_size_bytes * 1024))")
@@ -562,10 +586,28 @@ perform_cleanup() {
fi
fi
# Hint about Full Disk Access for better results (only if not already granted)
if [[ -t 1 && "$DRY_RUN" != "true" ]]; then
local fda_status=0
has_full_disk_access
fda_status=$?
if [[ $fda_status -eq 1 ]]; then
echo ""
echo -e "${YELLOW}${ICON_WARNING}${NC} ${GRAY}Tip: Grant Full Disk Access to your terminal in System Settings for best results${NC}"
fi
fi
total_items=0
files_cleaned=0
total_size_cleaned=0
local had_errexit=0
[[ $- == *e* ]] && had_errexit=1
# Allow cleanup functions to fail without exiting the script
# Individual operations use || true for granular error handling
set +e
# ===== 1. Deep system cleanup (if admin) - Do this first while sudo is fresh =====
if [[ "$SYSTEM_CLEAN" == "true" ]]; then
start_section "Deep system"
@@ -745,6 +787,11 @@ perform_cleanup() {
summary_details+=("Free space now: $(get_free_space)")
fi
# Restore strict error handling only if it was enabled
if [[ $had_errexit -eq 1 ]]; then
set -e
fi
print_summary_block "$summary_heading" "${summary_details[@]}"
printf '\n'
}