Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handling by exposing exceptions instead of silently consuming them #45

Conversation

d4rken
Copy link
Contributor

@d4rken d4rken commented Jul 21, 2021

This is a follow up to #44
Debugging was really difficult because there was no visible error.
ValidationResult already has a field to return errors that we can use, it was just set to null.

This PR:

  • Catch Exception not Throwable as the libraries should not quietly contain an Error being thrown.
  • Catch Exception map it to OPEN but save the exception and fill the validation result with any errors, otherwise set it to null.
  • Refactored the code a bit as it was really really really difficult to read. ❤️

The library should behave exactly the same to the outside, except that if there is an internal Exception being thrown, then ValidationResult.validationErrors is not null.

d4rken added 3 commits July 21, 2021 18:10
* Make exceptions available via unused `validationErrors` field
* Improve code readability.
@d4rken d4rken requested a review from a team as a code owner July 21, 2021 16:34
Comment on lines +70 to +82
if (rules.isEmpty()) return emptyList()

val dataJsonNode = prepareData(externalParameter, payload)
val hcertVersion: Triple<Int, Int, Int>? = hcertVersionString.toVersion()

return rules.map {
checkRule(
rule = it,
dataJsonNode = dataJsonNode,
hcertVersion = hcertVersion,
certificateType = certificateType
)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early return to prervent unnecessary nesting, then treat this as data preperation step.

Comment on lines +96 to +102
val isCompatibleVersion = rule.engine == CERTLOGIC_KEY &&
ruleEngineVersion != null &&
CERTLOGIC_VERSION.isGreaterOrEqualThan(ruleEngineVersion) &&
hcertVersion != null &&
schemaVersion != null &&
hcertVersion.first == schemaVersion.first &&
hcertVersion.isGreaterOrEqualThan(schemaVersion)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicit version compatibility check.

Comment on lines +104 to 116
val res = if (isCompatibleVersion) {
try {
when (jsonLogicValidator.isDataValid(rule.logic, dataJsonNode)) {
true -> Result.PASSED
false -> Result.FAIL
}
val cur: String = affectedFieldsDataRetriever.getAffectedFieldsData(
rule,
dataJsonNode,
certificateType
)
validationResults.add(
ValidationResult(
rule,
res,
cur,
null
)
)
} catch (e: Exception) {
validationErrors.add(e)
Result.OPEN
}
validationResults
} else {
emptyList()
Result.OPEN
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still map exceptions to OPEN, but store the Exception for the result.

Exception instead of Throwable to not catch Error.
https://stackoverflow.com/questions/6083248/is-it-a-bad-practice-to-catch-throwable

rule,
res,
cur,
if (validationErrors.isEmpty()) null else validationErrors
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could also just stay an empty list, but I didn't want to alter the behavior to the outside, e.g. if a library consumer checks for null.

@oleksandrsarapulovgl
Copy link
Contributor

This is a follow up to #44
Debugging was really difficult because there was no visible error.
ValidationResult already has a field to return errors that we can use, it was just set to null.

This PR:

  • Catch Exception not Throwable as the libraries should not quietly contain an Error being thrown.
  • Catch Exception map it to OPEN but save the exception and fill the validation result with any errors, otherwise set it to null.
  • Refactored the code a bit as it was really really really difficult to read. heart

The library should behave exactly the same to the outside, except that if there is an internal Exception being thrown, then ValidationResult.validationErrors is not null.

Thank you for the update! All comments definitely make sense

@oleksandrsarapulovgl oleksandrsarapulovgl merged commit 30cf728 into eu-digital-green-certificates:main Jul 22, 2021
@d4rken d4rken deleted the improve-error-handling branch July 22, 2021 07:39
@d4rken d4rken restored the improve-error-handling branch July 22, 2021 07:41
@d4rken d4rken deleted the improve-error-handling branch July 22, 2021 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants