JuliaLang / Pkg.jl

Pkg - Package manager for the Julia programming language
https://pkgdocs.julialang.org
Other
610 stars 251 forks source link

Better error messages if artifact rename fails #3827

Open nhz2 opened 4 months ago

nhz2 commented 4 months ago

This PR should improve error messages if an anti-virus prevents the temporary directory the artifact is unpacked into from being renamed or deleted. Ref #3822

The issue is that an error that occurs in a finally after a try and catch hides any error that occurred in the try.

The following is the message I get when I simulate rm and rename failing on Linux with this PR:

(jl_OE62qJ) pkg> add iso_codes_jll
   Resolving package versions...
┌ Error: your anti-virus may be interfering with artifact installation
└ @ Pkg.Artifacts ~/github/Pkg.jl/src/Artifacts.jl:80
┌ Warning: Failed to clean up temporary directory "/home/nathan/.julia/artifacts/jl_iBFnfP"
│   exception = fake rm error
└ @ Pkg.Artifacts ~/github/Pkg.jl/src/Artifacts.jl:384
┌ Error: your anti-virus may be interfering with artifact installation
└ @ Pkg.Artifacts ~/github/Pkg.jl/src/Artifacts.jl:80
┌ Warning: Failed to clean up temporary directory "/home/nathan/.julia/artifacts/jl_97yMLY"
│   exception = fake rm error
└ @ Pkg.Artifacts ~/github/Pkg.jl/src/Artifacts.jl:384
ERROR: Unable to automatically download/install artifact 'iso_codes' from sources listed in '/home/nathan/.julia/packages/iso_codes_jll/QEOzB/Artifacts.toml'.
Sources attempted:
- https://pkg.julialang.org/artifact/695a3abd0af051dab62687501b9a61ad91c831a3
    Error: IOError: rename of "/home/nathan/.julia/artifacts/jl_iBFnfP" to "/home/nathan/.julia/artifacts/695a3abd0af051dab62687501b9a61ad91c831a3": resource busy or locked (EBUSY)
- https://github.com/JuliaBinaryWrappers/iso_codes_jll.jl/releases/download/iso_codes-v4.15.1+0/iso_codes.v4.15.1.x86_64-linux-gnu.tar.gz
    Error: IOError: rename of "/home/nathan/.julia/artifacts/jl_97yMLY" to "/home/nathan/.julia/artifacts/695a3abd0af051dab62687501b9a61ad91c831a3": resource busy or locked (EBUSY)

Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] ensure_artifact_installed(name::String, meta::Dict{String, Any}, artifacts_toml::String; platform::Base.BinaryPlatforms.Platform, verbose::Bool, quiet_download::Bool, io::Pkg.UnstableIO)
    @ Pkg.Artifacts ~/github/Pkg.jl/src/Artifacts.jl:476
  [3] download_artifacts(env::Pkg.Types.EnvCache; platform::Base.BinaryPlatforms.Platform, julia_version::VersionNumber, verbose::Bool, io::Pkg.UnstableIO)
    @ Pkg.Operations ~/github/Pkg.jl/src/Operations.jl:770
  [4] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}, new_git::Set{Base.UUID}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform, target::Symbol)
    @ Pkg.Operations ~/github/Pkg.jl/src/Operations.jl:1433
  [5] add
    @ ~/github/Pkg.jl/src/Operations.jl:1399 [inlined]
  [6] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform, target::Symbol, kwargs::@Kwargs{io::Pkg.UnstableIO})
    @ Pkg.API ~/github/Pkg.jl/src/API.jl:307
  [7] add(pkgs::Vector{Pkg.Types.PackageSpec}; io::Pkg.UnstableIO, kwargs::@Kwargs{})
    @ Pkg.API ~/github/Pkg.jl/src/API.jl:160
  [8] add(pkgs::Vector{Pkg.Types.PackageSpec})
    @ Pkg.API ~/github/Pkg.jl/src/API.jl:149
  [9] do_cmd(command::Pkg.REPLMode.Command, io::Base.TTY)
    @ Pkg.REPLMode ~/github/Pkg.jl/src/REPLMode/REPLMode.jl:407
 [10] do_cmds(commands::Vector{Pkg.REPLMode.Command}, io::Base.TTY)
    @ Pkg.REPLMode ~/github/Pkg.jl/src/REPLMode/REPLMode.jl:393
 [11] do_cmds(repl::REPL.LineEditREPL, commands::String)
    @ REPLExt ~/github/Pkg.jl/ext/REPLExt/REPLExt.jl:92
 [12] (::REPLExt.var"#31#34"{REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::IOBuffer, ok::Bool)
    @ REPLExt ~/github/Pkg.jl/ext/REPLExt/REPLExt.jl:122
 [13] #invokelatest#2
    @ ./essentials.jl:1030 [inlined]
 [14] invokelatest
    @ ./essentials.jl:1027 [inlined]
 [15] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit ~/packages/julias/julia-latest/share/julia/stdlib/v1.12/REPL/src/LineEdit.jl:2744
 [16] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL ~/packages/julias/julia-latest/share/julia/stdlib/v1.12/REPL/src/REPL.jl:1406
 [17] (::REPL.var"#75#81"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL ~/packages/julias/julia-latest/share/julia/stdlib/v1.12/REPL/src/REPL.jl:456

Here is what this kind of error would look like before this PR (from https://discourse.julialang.org/t/installation-of-nodejs-fails-directory-not-empty/111117)

(tmp) pkg> add NodeJS
   Resolving package versions...
  Downloaded artifact: nodejs_app
ERROR: IOError: rm("C:\\Users\\michele.zaffalon\\.julia\\artifacts\\jl_Y9gBTl"): directory not empty (ENOTEMPTY)
Stacktrace:
  [1] uv_error
    @ .\libuv.jl:100 [inlined]
  [2] rm(path::String; force::Bool, recursive::Bool)
    @ Base.Filesystem .\file.jl:307
  [3] rm
    @ .\file.jl:273 [inlined]
  [4] download_artifact(tree_hash::Base.SHA1, tarball_url::String, tarball_hash::Nothing; verbose::Bool, quiet_download::Bool, io::Base.TTY)
\src\Artifacts.jl:376
  [5] download_artifact (repeats 2 times)
    @ C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Artifacts.jl:297 [inlined]
  [6] #22
    @ C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Artifacts.jl:423 [inlined]
  [7] with_show_download_info(f::Pkg.Artifacts.var"#22#24"{Bool, Bool, Base.TTY, Base.SHA1, String}, io::Base.TTY, name::String, quiet_download::Bool)
    @ Pkg.Artifacts C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Artifacts.jl:480
  [8] ensure_artifact_installed(name::String, meta::Dict{String, Any}, artifacts_toml::String; platform::Base.BinaryPlatforms.Platform, verbose::Bool, quiet_download::Bool, io::Base.TTY)
    @ Pkg.Artifacts C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Artifacts.jl:422
  [9] download_artifacts(env::Pkg.Types.EnvCache; platform::Base.BinaryPlatforms.Platform, julia_version::VersionNumber, verbose::Bool, io::Base.TTY)
    @ Pkg.Operations C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Operations.jl:755
 [10] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}, new_git::Set{Base.UUID}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform)
    @ Pkg.Operations C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Operations.jl:1394
 [11] add
    @ C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\Operations.jl:1376 [inlined]
 [12] add(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; preserve::Pkg.Types.PreserveLevel, platform::Base.BinaryPlatforms.Platform, kwargs::@Kwargs{io::Base.TTY})
    @ Pkg.API C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\API.jl:278
 [13] add(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::@Kwargs{})
    @ Pkg.API C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\API.jl:159
 [14] add(pkgs::Vector{Pkg.Types.PackageSpec})
    @ Pkg.API C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\API.jl:148
 [15] do_cmd!(command::Pkg.REPLMode.Command, repl::REPL.LineEditREPL)
    @ Pkg.REPLMode C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\REPLMode\REPLMode.jl:412
 [16] do_cmd(repl::REPL.LineEditREPL, input::String; do_rethrow::Bool)
    @ Pkg.REPLMode C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\REPLMode\REPLMode.jl:390
 [17] do_cmd
    @ C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\REPLMode\REPLMode.jl:380 [inlined]
 [18] (::Pkg.REPLMode.var"#24#27"{REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::IOBuffer, ok::Bool)
    @ Pkg.REPLMode C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Pkg\src\REPLMode\REPLMode.jl:557
 [19] #invokelatest#2
    @ .\essentials.jl:892 [inlined]
 [20] invokelatest
    @ .\essentials.jl:889 [inlined]
 [21] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\REPL\src\LineEdit.jl:2656
 [22] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\REPL\src\REPL.jl:1312
 [23] (::REPL.var"#62#68"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL C:\Users\michele.zaffalon\.julia\juliaup\julia-1.10.2+0.x64.w64.mingw32\share\julia\stdlib\v1.10\REPL\src\REPL.jl:386