Guard clauses for trace and span macros #130
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While updating one of our apps from Spandex 2.4.4 to 3.0.3, we hit an issue where it was crashing at runtime where it hadn't before. We traced it down to these new Spandex error logs that weren't using
inspect
and were failing to encode a keyword list of opts as a string, because at some earlier point, we had moved from using Decorators to using the Tracer macros and made a mistake in the conversion:From:
To:
Instead of:
The bug here was subtle: rather than passing in a name and opts, we're accidentally passing in our opts as the name, with the optional opts being defaulted to
[]
. Normally, that would have caused some other crash elsewhere when trying to use that name as a string, but in this case, we also had decorated this code as atrace
when it should have been aspan
, so the only thing that was happening is theLogger.error
message warning us that we already had an active trace, which we hadn't noticed yet and it wasn't causing a crash until the code was introduced to log the name.So anyway, with this change I am using
inspect
to protect those particular log messages against runtime exceptions and also adding guard clauses, which should be reasonably safe because the macro itself runs at compile time, so it generates a compiler error like the following if you're trying to call it wrong like we were:IMO, this is better than actually putting a guard clause on
Spandex.trace
because that would crash at runtime instead of compile time. Doing it this way means that when someone upgrades, the compiler will point them directly at the problem so they can fix it before they deploy new code. That being said, should this be considered a non-breaking change, because it will only require a code change if they're already calling the macro incorrectly? 🤔