Skip to content

Improve QR scanner error handling#811

Merged
gudnuf merged 6 commits intomasterfrom
qr-scanner-error-handling
Feb 14, 2026
Merged

Improve QR scanner error handling#811
gudnuf merged 6 commits intomasterfrom
qr-scanner-error-handling

Conversation

@gudnuf
Copy link
Contributor

@gudnuf gudnuf commented Feb 2, 2026

Summary

  • Keep scanner running after validation errors instead of showing blank screen
  • Deduplicate rapid scan events to prevent toast spam while QR is held up
  • Show specific error messages for DomainErrors in send scanner
  • Rename receive scan component to receive-scanner for consistency

🤖 Assisted by Claude Code

@vercel
Copy link

vercel bot commented Feb 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agicash Ready Ready Preview, Comment Feb 14, 2026 10:34pm

Request Review

@supabase
Copy link

supabase bot commented Feb 2, 2026

This pull request has been ignored for the connected project hrebgkfhjpkbxpztqqke because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

const handleDecode = async (input: string): Promise<boolean> => {
const selectDestinationResult = await selectDestination(input);
if (!selectDestinationResult.success) {
// TODO: implement this https://github.com/MakePrisms/agicash/pull/331#discussion_r2024690976
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 took a different approach to this. Now the scanner keeps scanning if there's an error and I show the toast. We needed to add the cooldown to the qr-scanner otherwise if there's an error it will continue decoding and erroring and spamming the toasts

@gudnuf gudnuf requested a review from jbojcic1 February 2, 2026 19:42
@gudnuf gudnuf self-assigned this Feb 2, 2026
@gudnuf gudnuf added the P2 Medium priority label Feb 2, 2026
@gudnuf gudnuf requested a review from jbojcic1 February 2, 2026 23:48
setCurrentFragment('');
decodeRef.current(decoded);
scanner.current?.destroy();
await handleDecodeRef.current(decoded);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this approach is wrong. Correct me if I am wrong, but every time after successful decode we are navigating to another route? If so, maybe we should destroy the scanner on component unmount instead of after decode. In that case the scanner would just be concerned with scanning and if you want to stop scanning you just need to unmount the component

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yea good point. I changed things a bit so that now it only destroy on unmount which is nice because we can remove the scannerRef

Copy link
Collaborator

@jbojcic1 jbojcic1 Feb 4, 2026

Choose a reason for hiding this comment

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

I feel like this can be even simpler. How does useAnimatedQRDecoder work? Lets forget other things for a bit now and say that camera is on and you just have conosle.log here in onDecode. Does it keep firing as long as you keep scanning the qr code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yea. It fires everytime it decodes and is constantly trying to decode. So the logs will be spaced apart by however long it takes to decode

Copy link
Collaborator

Choose a reason for hiding this comment

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

@gudnuf here is how I'd do it then #856

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've been doing this a lot, so I created this skill. I iterated on it a couple times, but the fisrt version of it gave me this output below when I started addressing your feedback. This was a super simple PR, so I'll keep iterating on this skill as I use it. I also started a pr-feedback-final-check skill that starts a fresh context and makes sure all comments were properly addressed and that no new issues were introduced, but I need to work on that one some more.

Image

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 tried to make it reflect how our review process works, so lmk if there's anything you think that should be different. We may also need to change this or create a new one so that we can give it to claude in github to address our feedback, but I've been finding the most success with just doing it locally so its optimized for that

Copy link
Collaborator

Choose a reason for hiding this comment

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

one thing we should also instruct claude to do (I am not sure if skill is the way to do it or something else), is to make a temp test and verify some behavior when not sure. I caught him few times doing something that it wasn't sure about and then I would tell it fi you can't find make a small test and lets see how it works and that worked pretty well. would be great if it could do that on its own

variant: 'destructive',
});
return;
throw new Error('Invalid cashu token');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure about this usage. I wanted the qr-scanner to be able to handle the error cooldown, but I didn't want it do toasts because that seems like something the caller should do. So the way this is now, the caller can toast if they want, then they throw an error to signal to the scanner that it should pause calling onDecode until the cooldown.

Another idea I had was make these components handle the cooldown and not toast until after the cooldown expires.

wdyt? previously, I had this returning false to tell the scanner an error occurred but that seemed a bit wrong

- Keep scanner running after validation errors instead of showing blank screen
- Deduplicate rapid scan events to prevent toast spam while QR is held up
- Show specific error messages for DomainErrors in send scanner
- Rename receive scan component to receive-scanner for consistency
@gudnuf gudnuf merged commit b577bc6 into master Feb 14, 2026
6 checks passed
@gudnuf gudnuf deleted the qr-scanner-error-handling branch February 14, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants