From a8a29731a50f8eb725fe3752243a28049dcaae84 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 25 Jul 2022 01:25:09 +0200 Subject: [PATCH] Implement HYPREError for nicer error messages This patch adds HYPREError <: Exception which is thrown when a HYPRE_ function returns an error code. HYPRE_ClearAllErrors() are called just before throwing. --- src/LibHYPRE.jl | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/LibHYPRE.jl b/src/LibHYPRE.jl index 77e824e..9f424b1 100644 --- a/src/LibHYPRE.jl +++ b/src/LibHYPRE.jl @@ -41,14 +41,39 @@ end @setprecond HYPRE_ParCSRPCGSetPrecond(solver, precond, precond_setup, precond_solver) +struct HYPREError <: Exception + fn::Symbol + ierr::HYPRE_Int +end + +# See HYPRE_DescribeError(HYPRE_Int ierr, char *msg) +function Base.showerror(io::IO, h::HYPREError) + print(io, "LibHYPRE.$(h.fn) returned error code $(h.ierr):") + if (h.ierr & HYPRE_ERROR_GENERIC) != 0 + print(io, " [Generic error]") + end + if (h.ierr & HYPRE_ERROR_MEMORY) != 0 + print(io, " [Memory error]") + end + if (h.ierr & HYPRE_ERROR_ARG) != 0 + arg = h.ierr >> 3 & 31 # See HYPRE_GetErrorArg() + print(io, " [Error in argument $arg]") + end + if (h.ierr & HYPRE_ERROR_CONV) != 0 + print(io, " [Method did not converge]") + end + return nothing +end + # Macro for checking LibHYPRE return codes macro check(arg) Meta.isexpr(arg, :call) || throw(ArgumentError("wrong usage of @check")) - msg = "LibHYPRE.$(arg.args[1]) returned non-zero return code: " return quote r = $(esc(arg)) if r != 0 - error(string($msg, r)) + # Since we throw here we can clear the errors (I think?) + HYPRE_ClearAllErrors() + throw(HYPREError($(QuoteNode(arg.args[1])), r)) end r end