Skip to content

Commit

Permalink
Merge pull request #243 from LCSB-BioCore/mk-softer-error-reporting
Browse files Browse the repository at this point in the history
make throwing SBML load errors configurable
  • Loading branch information
exaexa authored Jan 31, 2023
2 parents d174aed + 630b4aa commit 89a29d8
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
24 changes: 17 additions & 7 deletions src/readsbml.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,15 @@ function _readSBML(
fn::String,
sbml_conversion,
report_severities,
throw_severities,
)::SBML.Model
doc = ccall(sbml(symbol), VPtr, (Cstring,), fn)
try
get_error_messages(
doc,
AssertionError("Opening SBML document has reported errors"),
report_severities,
throw_severities,
)

sbml_conversion(doc)
Expand Down Expand Up @@ -207,8 +209,9 @@ single parameter, which is the C pointer to the loaded SBML document (C type
[`set_level_and_version`](@ref), [`libsbml_convert`](@ref),
[`convert_simplify_math`](@ref) and [`convert_promotelocals_expandfuns`](@ref).
`report_severities` switches on and off reporting of certain errors; see the
documentation of [`get_error_messages`](@ref) for details.
`report_severities` and `throw_severities` switch on and off reporting of
certain errors; see the documentation of [`get_error_messages`](@ref) for
details.
To read from a string instead of a file, use [`readSBMLFromString`](@ref).
Expand All @@ -223,10 +226,11 @@ end)
function readSBML(
fn::String,
sbml_conversion = document -> nothing;
report_severities = ["Fatal", "Error"],
report_severities = ["Error"],
throw_severities = ["Fatal"],
)::SBML.Model
isfile(fn) || throw(AssertionError("$(fn) is not a file"))
_readSBML(:readSBML, fn, sbml_conversion, report_severities)
_readSBML(:readSBML, fn, sbml_conversion, report_severities, throw_severities)
end

"""
Expand All @@ -240,9 +244,15 @@ used to read from a file instead of a string.
readSBMLFromString(
str::AbstractString,
sbml_conversion = document -> nothing;
report_severities = ["Fatal", "Error"],
)::SBML.Model =
_readSBML(:readSBMLFromString, String(str), sbml_conversion, report_severities)
report_severities = ["Error"],
throw_severities = ["Fatal"],
)::SBML.Model = _readSBML(
:readSBMLFromString,
String(str),
sbml_conversion,
report_severities,
throw_severities,
)

get_notes(x::VPtr)::Maybe{String} = get_optional_string(x, :SBase_getNotesString)
get_annotation(x::VPtr)::Maybe{String} = get_optional_string(x, :SBase_getAnnotationString)
Expand Down
17 changes: 13 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -367,26 +367,34 @@ Show the error messages reported by SBML in the `doc` document and throw the
`report_severities` switches the reporting of certain error types defined by
libsbml; you can choose from `["Fatal", "Error", "Warning", "Informational"]`.
`throw_severities` selects errors on which the functions throws the `error`.
"""
function get_error_messages(doc::VPtr, error::Exception, report_severities)
function get_error_messages(
doc::VPtr,
error::Exception,
report_severities,
throw_severities,
)
n_errs = ccall(sbml(:SBMLDocument_getNumErrors), Cuint, (VPtr,), doc)
do_throw = false
for i = 1:n_errs
err = ccall(sbml(:SBMLDocument_getError), VPtr, (VPtr, Cuint), doc, i - 1)
msg = string(strip(get_string(err, :XMLError_getMessage)))
sev = string(strip(get_string(err, :XMLError_getSeverityAsString)))

# keywords from `libsbml/src/sbml/xml/XMLError.cpp` xmlSeverityStringTable:
if sev == "Fatal"
sev in report_severities && @error "SBML reported fatal error: $(msg)"
do_throw = true
elseif sev == "Error"
sev in report_severities && @error "SBML reported error: $(msg)"
do_throw = true
elseif sev == "Warning"
sev in report_severities && @warn "SBML reported warning: $(msg)"
elseif sev == "Informational"
sev in report_severities && @info "SBML reported: $(msg)"
end

sev in throw_severities && (do_throw = true)
end
do_throw && throw(error)
nothing
Expand All @@ -406,7 +414,8 @@ check_errors(
doc::VPtr,
error::Exception,
report_severities = ["Fatal", "Error"],
) = Bool(success) || get_error_messages(doc, error, report_severities)
throw_severities = ["Fatal", "Error"],
) = Bool(success) || get_error_messages(doc, error, report_severities, throw_severities)

"""
$(TYPEDSIGNATURES)
Expand Down

0 comments on commit 89a29d8

Please sign in to comment.