chore(IT-Wallet): [SIW-3468] Add origin to serialize failure reason to enhance mixpanel tracking on unexpected failures#7684
Conversation
PR Title Validation for conventional commit type✅ All good! PR title follows the conventional commit type. |
Jira Pull Request LinkThis Pull Request refers to Jira issues: |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #7684 +/- ##
==========================================
+ Coverage 58.66% 61.45% +2.78%
==========================================
Files 1990 1882 -108
Lines 37796 35817 -1979
Branches 6143 5887 -256
==========================================
- Hits 22173 22011 -162
+ Misses 14316 12511 -1805
+ Partials 1307 1295 -12
... and 166 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
I am not totally convinced of this new Was it asked explicitly by the analytics team? |
|
@gispada |
| const reason = !failure.reason | ||
| ? "Reason not provided" | ||
| : failure.reason instanceof Error | ||
| ? createReasonObject(failure.reason.message) | ||
| ? createReasonObject(failure.reason.message, origin) | ||
| : failure.reason; |
There was a problem hiding this comment.
When failure.reason is not an Error (e.g., it's already a structured object), the origin parameter is ignored entirely.
What do you think about doing something like this?
const reason = !failure.reason
? createReasonObject("Reason not provided", origin)
: failure.reason instanceof Error
? createReasonObject(failure.reason.message, origin)
: typeof failure.reason === "object"
? { ...failure.reason, origin }
: failure.reason;
There was a problem hiding this comment.
Make sense to me.
Should we make a guard to avoid concatenating so many ternary and extends the check to more types of entities?
There was a problem hiding this comment.
Sorry, I forgot to answer your question. If you think it is useful sure, it should be fine.
There was a problem hiding this comment.
Added it.
Lmk if anything else should be adjusted
|
|
||
| export type TrackItWalletCieCardReadingUnexpectedFailure = { | ||
| reason: string | undefined; | ||
| reason: string | unknown | undefined; |
There was a problem hiding this comment.
reason is string | unknown | undefined;, but in the code is always an object with origin and name. Is there a reason for this?
Btw, if we want to enrich the event we should prefer adding a new property instead of changing the ones already present.
There was a problem hiding this comment.
I added unknown because reason was no longer a plain string in this event: we started sending { origin, name }. Keeping origin inside reason was agreed with the CXM team for these unexpected failures.
Re-thinking about it adding unknown doesn't give any advantage. I replaced it with the curent shape
There was a problem hiding this comment.
We should not change properties that we already sending to Mixpanel. Instead, we should extend them. In this case we should have:
export type TrackItWalletCieCardReadingUnexpectedFailure = {
reason: string | undefined;
origin: string | undefined;
cie_reading_progress: number;
itw_flow: ItwFlow;
ITW_ID_method?: ItwIdMethod;
};
This will not break the previous event tracking
There was a problem hiding this comment.
You are right, I was looking at the serializer.
Atp should we allso modify the current serialization in itwStoreUtils.tsx? Instead of creating an object with extended reason, maybe we can extend the shape with origin outside.
What do you think?
There was a problem hiding this comment.
What do you mean? Can you give me an example?
There was a problem hiding this comment.
I thought about 2 possible solution:
Instead of creating an object with origin inside:
const createReasonObject = (message: string, origin?: string) => ({
code: "UNEXPECTED",
errorDescription: message,
origin
});
We can pass it outside in the function, something like:
export const serializeFailureReason = (
failure:
| IssuanceFailure
| CredentialIssuanceFailure
| RemoteFailure
| ProximityFailure,
origin?: string
) => ({
...failure,
reason: mapFailureReason(failure.reason),
origin
});
This could actually may be misleading because this function is probably born to recreate reason.
A better solution could be instead of passing the origin at the function as is:
return trackItwIdRequestUnexpectedFailure(
shouldSerializeReason(failure)
? {
...serializeFailureReason(failure, "ITW_EID_EVENTS_TRACKING"),
itw_flow: itwFlow
}
: { ...failure, itw_flow: itwFlow }
);
We can maybe populate it outside, something like:
return trackItwIdRequestUnexpectedFailure(
shouldSerializeReason(failure)
? {
...serializeFailureReason(failure),
itw_flow: itwFlow,
origin: 'ITW_EID_EVENTS_TRACKING'
}
: { ...failure, itw_flow: itwFlow }
);
I'm not sure about this because the request was to give more insight on reason, and doing so it feels like we are losing the focus.
There was a problem hiding this comment.
Yes serializeFailureReason doesn't need to have origin. Let's keep things simple
There was a problem hiding this comment.
I extracted the logic to keep origin outside serializeFailureReason.
The parameter origin is now sent directly from the event
…acking events to include origin
| const isReasonObject = (reason: unknown): reason is object => | ||
| typeof reason === "object" && reason !== null; |
There was a problem hiding this comment.
Do you think that having a dedicated function for typeof reason === "object" is overkill?
There was a problem hiding this comment.
At this point yes, is only used once. I think inlining it would be better
…s helper function
Short description
Add origin context to all “unexpected” IT Wallet analytics events so Mixpanel receives more actionable reasons instead of generic
UNEXPECTEDvalues.List of changes proposed in this pull request
How to test
Unexpected test cases are unpredictable; in the current state, I couldn't cover the tests for this scenario.