From b044bf6a239c5341164968a6a0d1a610b2ea431a Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 8 Aug 2023 20:38:12 -0500 Subject: [PATCH] precompile: pipe error messages during autoprecompilation to Main.err for easier inspection (#3536) - Sends errors during autoprecompilation to Main.err for inspection - Or if noninteractive just shows autoprecompilation errors without throwing --- src/API.jl | 44 +++++++++++++++++++++++++------------------- src/Types.jl | 13 ++++++++++++- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/API.jl b/src/API.jl index e9bd69ced4..eb83a9a2b0 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1542,12 +1542,6 @@ function precompile(ctx::Context, pkgs::Vector{PackageSpec}; internal_call::Bool " dependenc$(pluralpc) failed but may be precompilable after restarting julia" ) end - if internal_call && !isempty(failed_deps) - plural1 = length(failed_deps) == 1 ? "y" : "ies" - plural2 = length(failed_deps) == 1 ? "" : "s" - print(iostr, "\n ", color_string("$(length(failed_deps))", Base.error_color()), " dependenc$(plural1) errored. ") - print(iostr, "To see a full report either run `import Pkg; Pkg.precompile()` or load the package$(plural2)") - end end # show any stderr output, even if Pkg.precompile has been interrupted (quick_exit=true), given user may be # interrupting a hanging precompile job with stderr output. julia#48371 @@ -1568,20 +1562,32 @@ function precompile(ctx::Context, pkgs::Vector{PackageSpec}; internal_call::Bool end end quick_exit && return - if !internal_call - err_str = "" - n_direct_errs = 0 - for (dep, err) in failed_deps - if strict || (dep in direct_deps) - err_str = string(err_str, "\n$dep\n\n$err", (n_direct_errs > 0 ? "\n" : "")) - n_direct_errs += 1 - end + err_str = "" + n_direct_errs = 0 + for (dep, err) in failed_deps + if strict || (dep in direct_deps) + err_str = string(err_str, "\n$dep\n\n$err", (n_direct_errs > 0 ? "\n" : "")) + n_direct_errs += 1 end - if err_str != "" - println(io, "") - pluralde = n_direct_errs == 1 ? "y" : "ies" - direct = strict ? "" : "direct " - pkgerror("The following $n_direct_errs $(direct)dependenc$(pluralde) failed to precompile:\n$(err_str[1:end-1])") + end + if err_str != "" + pluralde = n_direct_errs == 1 ? "y" : "ies" + direct = strict ? "" : "direct " + err_msg = "The following $n_direct_errs $(direct)dependenc$(pluralde) failed to precompile:\n$(err_str[1:end-1])" + if internal_call # aka. auto-precompilation + if isinteractive() && !get(ENV, "CI", false) + plural1 = length(failed_deps) == 1 ? "y" : "ies" + println(io, " ", color_string("$(length(failed_deps))", Base.error_color()), " dependenc$(plural1) errored.") + println(io, " For a report of the errors see `julia> err`") + setglobal!(Base.MainInclude, :err, PkgPrecompileError(err_msg)) + else + # auto-precompilation shouldn't throw but if the user can't easily access the + # error messages, just show them + print(io, "\n", err_msg) + end + else + println(io) + pkgerror(err_msg) end end end diff --git a/src/Types.jl b/src/Types.jl index 4db6bbbb13..5a287af67e 100644 --- a/src/Types.jl +++ b/src/Types.jl @@ -22,7 +22,8 @@ using SHA export UUID, SHA1, VersionRange, VersionSpec, PackageSpec, PackageEntry, EnvCache, Context, GitRepo, Context!, Manifest, Project, err_rep, - PkgError, pkgerror, has_name, has_uuid, is_stdlib, stdlib_version, is_unregistered_stdlib, stdlibs, write_env, write_env_usage, parse_toml, + PkgError, pkgerror, PkgPrecompileError, + has_name, has_uuid, is_stdlib, stdlib_version, is_unregistered_stdlib, stdlibs, write_env, write_env_usage, parse_toml, project_resolve!, project_deps_resolve!, manifest_resolve!, registry_resolve!, stdlib_resolve!, handle_repos_develop!, handle_repos_add!, ensure_resolved, registered_name, manifest_info, @@ -69,6 +70,16 @@ end pkgerror(msg::String...) = throw(PkgError(join(msg))) Base.showerror(io::IO, err::PkgError) = print(io, err.msg) +################# +# Pkg Precompile Error # +################# +struct PkgPrecompileError <: Exception + msg::String +end +Base.showerror(io::IO, err::PkgPrecompileError) = print(io, err.msg) +# This needs a show method to make `julia> err` show nicely +Base.show(io::IO, err::PkgPrecompileError) = print(io, "PkgPrecompileError: ", err.msg) + ############### # PackageSpec #