fix: attach resource context to reported listener errors; stop retrying permission-denied - #50
Draft
posthog[bot] wants to merge 1 commit into
Conversation
…rying permission-denied store.reportError now wraps every error in a FirestateError that carries type, path, operation, and the Firestore code on own fields, keeps the original on cause, and puts the path in the message. A consumer that forwards only the first argument to an error tracker keeps the context and gets a distinct fingerprint per resource. Context still travels as the second onError argument. The listener retry branch now treats a terminal Firestore code (permission-denied, unauthenticated) as terminal even when retryOnError is set: it reports the error, sets state.error, and clears isLoading instead of re-attaching the listener every retryInterval behind a spinner that never resolves. Only transient codes still retry. Generated-By: PostHog Code Task-Id: 22c2ca54-66e1-40e9-9799-2942e40ad4ac
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
onSnapshoterror callbacks build the right context (type, path,operation: 'read'), butstore.reportErrorpasses the rawFirebaseErroras argument one and the context as a separate argument two. A consumer that forwards only the first argument to an error tracker loses the path and the distinct fingerprint.retryOnError: true, the listener handler only did aconsole.warnand re-attached everyretryInterval(5s). It never setstate.errorand never reported.permission-deniedis not transient, so that is an endless retry behind a spinner that never resolves. This bug is latent today — nothing here opts intoretryOnError.Changes
store.reportErrornow wraps every error in a newFirestateError. The wrapper puts the path in the message and holdstype,path,operation, and the Firestorecodeon own fields, with the original error oncause. A consumer that forwards only the error keeps a usable path and gets a distinct fingerprint per resource. Thecontextobject still arrives as the secondonErrorargument.permission-deniedis terminal. The listener retry branch now checks the Firestore code. A terminal code (permission-denied,unauthenticated) reports the error, setsstate.error, and clearsisLoading— even whenretryOnErroris set. Only transient codes (e.g.unavailable) still re-attach the listener. This matches the policy the write paths already use.FirestateErroris exported from the public entry point.Behavior
permission-denied,retryOnError: truestate.errorset,isLoadingclearedunavailable,retryOnError: trueonErrorFirestateErrorwith path/type/operation/code, context still arg 2Tests
src/__tests__/listener-error.test.ts: wrapped-error context and path, distinct fingerprints per resource,permission-deniedterminal for document and collection, transient error still retries.src/core/store.test.tsfor the wrapped-error contract (code copy, no double-wrap, undo path).pnpm typecheck,pnpm build, and the full test suite (269 passed, 3 skipped) all pass.Why
A rare handled exception (1 occurrence, 1 user, 1 session in 30 days) exposed two code defects. The value is not the single event — it is stopping every future rules denial from collapsing into one opaque bucket, and closing a latent endless-retry loop before anyone opts into
retryOnError.Agent context
reportErrorrather than at each call site, so read, write, and undo paths all benefit and the fix stays in one place.Created with PostHog Desktop from this inbox report.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Fix listener error handling to attach resource context and skip retries on permission-denied
FirestateErrorinsrc/core/errors.tsthat wraps errors withtype,path,operation, and Firestorecode, and includes the resource path in the message.store.reportErrorinsrc/core/store.tsnow wraps errors inFirestateErrorbefore passing toonErrororconsole.error, preventing double-wrapping.permission-deniedandunauthenticatedFirestore codes as terminal: they setstate.error, clearisLoading, and report immediately instead of scheduling a retry, even whenretryOnErroris true.FirestateErroris exported from the package entry point so consumers can import and inspect it.retryOnError: truewould retry all listener errors; terminal Firestore codes now bypass retry logic entirely.Macroscope summarized 011aa51.