firebase / firebase/firebase-tools

Improve error message when invalid Firestore document path is specified in Firestore trigger definitions

Open
#4,284 8 comments 0 reactions 0 assignees View on GitHub
api: functions api: http help-wanted type: feature request
Dominant language
TypeScript
Stars
4.5k
Forks
1.3k
Avg merge
1d 12h
Merged PRs (30d)
84

Description

Wasn't really sure what to label this, so feel free to change it to something clearer.

### Related issues

Related, closed issue from 2018 fixed by fix of bug in grpc: firebase/firebase-functions#536 .

### [REQUIRED] Version info

Versions:

**node:** 16.13.0

**firebase-functions:** 3.18.1

**firebase-tools:** 10.2.2 (Also happened with 10.1.2)

**firebase-admin:** 10.0.2

### [REQUIRED] Test case

`index.ts` (looks mostly the same transpiled).
```
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

const app = admin.apps[0] ?? admin.initializeApp();

const testFunction = functions.https.onRequest(async (req, res) => {
try {
await app.firestore().collection('test').doc('test').set({ test: true });
res.send(true);
} catch (e) {
console.error(e);
res.send(false);
}
});

export default testFunction;
```

### [REQUIRED] Steps to reproduce

1. Compile the typescript
2. Run the function on the emulator using `firebase emulators:start`.
3. Send a request to `http://localhost:5001/{projectId}/{location}/default`
4. See in the console that we get an error with the note "Exception occurred in retry method that was not classified as transient". Complete error message below.

### [REQUIRED] Expected behavior
The collection "test" should have a document "test" with a value "test":true in it.

### [REQUIRED] Actual behavior

Sporadically, it seems to work, this might have something to do with cold starts? I don't know how that works on the emulator.

The logged exception:
```
Error: 2 UNKNOWN:
> at Object.callErrorFromStatus (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@grpc\grpc-js\build\src\call.js:31:26)
> at Object.onReceiveStatus (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@grpc\grpc-js\build\src\client.js:180:52)
> at Object.onReceiveStatus (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@grpc\grpc-js\build\src\client-interceptors.js:365:141)
> at Object.onReceiveStatus (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@grpc\grpc-js\build\src\client-interceptors.js:328:181)
> at C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@grpc\grpc-js\build\src\call-stream.js:182:78
> at processTicksAndRejections (node:internal/process/task_queues:78:11)
> Caused by: Error
> at WriteBatch.commit (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@google-cloud\firestore\build\src\write-batch.js:417:23)
> at DocumentReference.set (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\@google-cloud\firestore\build\src\reference.js:355:14)
> at C:\Users\Even\dev\flatz\app-2.0\functions\lib\index.js:9:62
> at C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:574:16
> at runFunction (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:547:15)
> at runHTTPS (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:573:11)
> at handler (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:493:23)
> at Layer.handle [as handle_request] (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5)
> at next (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\node_modules\express\lib\router\route.js:137:13)
> at Route.dispatch (C:\Users\Even\dev\flatz\app-2.0\functions\node_modules\firebase-tools\node_modules\express\lib\router\route.js:112:3) {
> code: 2,
> details: '',
> metadata: Metadata {
> internalRepr: Map(1) { 'content-type' => [Array] },
> options: {}
> },
> note: 'Exception occurred in retry method that was not classified as transient'
```

The error message showing up in firestore-debug.log:

```
Mar 10, 2022 7:58:49 PM com.google.cloud.datastore.emulator.impl.util.WrappedStreamObserver onError
INFO: operation failed: Invalid pattern. Reason: [76:] Expected '}' at end of capture expression.
java.lang.IllegalArgumentException: Invalid pattern. Reason: [76:] Expected '}' at end of capture expression.
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:147)
at com.google.firebase.rules.eventflow.client.path.PathPattern.compileInternal(PathPattern.java:78)
at com.google.firebase.rules.eventflow.client.path.PathPattern.compile(PathPattern.java:50)
at com.google.firebase.rules.eventflow.client.EventRuleEvaluatorImpl.lambda$new$0(EventRuleEvaluatorImpl.java:58)
at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:447)
at com.google.firebase.rules.eventflow.client.EventRuleEvaluatorImpl.(EventRuleEvaluatorImpl.java:52)
at com.google.firebase.rules.eventflow.client.EventRuleEvaluatorImpl.(EventRuleEvaluatorImpl.java:39)
at com.google.cloud.datastore.emulator.impl.events.EventManager.reportEvents(EventManager.java:84)
at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1.commitHelper(CloudFirestoreV1.java:891)
at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1.internalCommit(CloudFirestoreV1.java:780)
at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1.commit(CloudFirestoreV1.java:416)
at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1Router.commit(CloudFirestoreV1Router.java:137)
at com.google.cloud.datastore.emulator.firestore.v1.FirestoreV1GrpcAdapter$1.lambda$commit$8(FirestoreV1GrpcAdapter.java:156)
at com.google.cloud.datastore.emulator.firestore.v1.FirestoreV1GrpcAdapter.unary(FirestoreV1GrpcAdapter.java:67)
at com.google.cloud.datastore.emulator.firestore.v1.FirestoreV1GrpcAdapter.access$000(FirestoreV1GrpcAdapter.java:39)
at com.google.cloud.datastore.emulator.firestore.v1.FirestoreV1GrpcAdapter$1.commit(FirestoreV1GrpcAdapter.java:156)
at com.google.firestore.v1.FirestoreGrpc$MethodHandlers.invoke(FirestoreGrpc.java:1224)
at io.grpc.stub.ServerCalls$UnaryServerCallHandler$UnaryServerCallListener.onHalfClose(ServerCalls.java:182)
at io.grpc.PartialForwardingServerCallListener.onHalfClose(PartialForwardingServerCallListener.java:35)
at io.grpc.ForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:23)
at io.grpc.ForwardingServerCallListener$SimpleForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:40)
at io.grpc.Contexts$ContextualizedServerCallListener.onHalfClose(Contexts.java:86)
at io.grpc.PartialForwardingServerCallListener.onHalfClose(PartialForwardingServerCallListener.java:35)
at io.grpc.ForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:23)
at io.grpc.ForwardingServerCallListener$SimpleForwardingServerCallListener.onHalfClose(ForwardingServerCallListener.java:40)
at io.grpc.Contexts$ContextualizedServerCallListener.onHalfClose(Contexts.java:86)
at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.halfClosed(ServerCallImpl.java:331)
at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed.runInContext(ServerImpl.java:866)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
```

I can see that it expects an ending bracket `}`, but I can't figure out where it expects it.

### Were you able to successfully deploy your functions?
Don't know if this is relevant, when I can't run them locally.

I've also attached my complete logs, but I'm pretty sure I've pasted the relevant parts.
[firebase-debug.log](https://github.com/firebase/firebase-functions/files/8226327/firebase-debug.log)
[firestore-debug.log](https://github.com/firebase/firebase-functions/files/8226328/firestore-debug.log)

Contributor guide

Open the contributing guide

Research direction

No repository file or test is named. Start with the firebase emulators:start path and compare the Firestore emulator's PathPattern.compile stack entries with firestore-debug.log; reproduce the invalid trigger-path case, since the body currently shows only an HTTPS function. Done means the invalid path produces a clear actionable error instead of the raw gRPC failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
cli, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.