Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: capture error stacks across async calls #1088

Merged
merged 9 commits into from May 27, 2020
Merged

Conversation

thebrianchen
Copy link

Fixes #1080.

Tested for get/set operations on references, queries, batches, and bulkCommit.

@thebrianchen thebrianchen self-assigned this May 21, 2020
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label May 21, 2020
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

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

You showed me a test case for this earlier - would it be possible to add a single System Test for one of the entry points?

I also wonder if Errror().stack generates some overhead since the documentation says that "stack" is lazily generated. If you have time, can you benchmark a single call?

return this.writeBatch.bulkCommit();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Move bang here.

Copy link
Author

Choose a reason for hiding this comment

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

done.

dev/src/index.ts Outdated
@@ -908,9 +908,15 @@ export class Firestore {
documentRefsOrReadOptions
);
const tag = requestTag();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Move bang here.

Copy link
Author

Choose a reason for hiding this comment

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

done.

dev/src/pool.ts Outdated
@@ -17,7 +17,7 @@
import * as assert from 'assert';

import {logger} from './logger';
import {Deferred} from './util';
import {Deferred, wrapError} from './util';
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused import?

Copy link
Author

Choose a reason for hiding this comment

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

removed.

@@ -1808,12 +1808,15 @@ export class Query<T = DocumentData> {
_get(transactionId?: Uint8Array): Promise<QuerySnapshot<T>> {
const docs: Array<QueryDocumentSnapshot<T>> = [];

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Move bang here.

Copy link
Author

Choose a reason for hiding this comment

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

done.

@@ -532,7 +532,13 @@ export class WriteBatch {
* });
*/
commit(): Promise<WriteResult[]> {
return this.commit_();

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Remove empty line.

Copy link
Author

Choose a reason for hiding this comment

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

done.

return this.commit_();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Move bang here.

Copy link
Author

Choose a reason for hiding this comment

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

done.

Copy link
Author

@thebrianchen thebrianchen left a comment

Choose a reason for hiding this comment

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

Did some benchmarking. Across 2500 calls to ref.get() the average RTT is 63.4ms for stack tracing vs. 60.1ms for no stack tracing. The spread was pretty wide though, with times in the +/- 10ms range. Calls to ref.set() were similar.

return this.writeBatch.bulkCommit();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Author

Choose a reason for hiding this comment

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

done.

dev/src/index.ts Outdated
@@ -908,9 +908,15 @@ export class Firestore {
documentRefsOrReadOptions
);
const tag = requestTag();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Author

Choose a reason for hiding this comment

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

done.

dev/src/pool.ts Outdated
@@ -17,7 +17,7 @@
import * as assert from 'assert';

import {logger} from './logger';
import {Deferred} from './util';
import {Deferred, wrapError} from './util';
Copy link
Author

Choose a reason for hiding this comment

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

removed.

@@ -1808,12 +1808,15 @@ export class Query<T = DocumentData> {
_get(transactionId?: Uint8Array): Promise<QuerySnapshot<T>> {
const docs: Array<QueryDocumentSnapshot<T>> = [];

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Author

Choose a reason for hiding this comment

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

done.

@@ -532,7 +532,13 @@ export class WriteBatch {
* });
*/
commit(): Promise<WriteResult[]> {
return this.commit_();

Copy link
Author

Choose a reason for hiding this comment

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

done.

return this.commit_();

// Capture the error stack to preserve stack tracing across async calls.
const stack = Error().stack;
Copy link
Author

Choose a reason for hiding this comment

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

done.

const ref = randomCol.doc('__doc__');
const batch = firestore.batch();
batch.set(ref, {foo: 'a'});
return batch.commit().then(() => Promise.reject('commit() should have failed')
Copy link
Contributor

Choose a reason for hiding this comment

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

I am glad this is causing a lint failure :) Doesn't look pretty like this. The PR is good to go after yarn gts fix.

Copy link
Author

Choose a reason for hiding this comment

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

fixed. Also I changed wrapError() to use GoogleError in order to preserve error codes when re-throwing.

@thebrianchen thebrianchen added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label May 22, 2020
@codecov
Copy link

codecov bot commented May 22, 2020

Codecov Report

Merging #1088 into master will decrease coverage by 0.14%.
The diff coverage is 93.47%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1088      +/-   ##
==========================================
- Coverage   97.62%   97.48%   -0.15%     
==========================================
  Files          27       27              
  Lines       16924    16960      +36     
  Branches     1347     1267      -80     
==========================================
+ Hits        16522    16533      +11     
- Misses        399      423      +24     
- Partials        3        4       +1     
Impacted Files Coverage Δ
dev/src/util.ts 98.17% <81.25%> (-1.83%) ⬇️
dev/src/bulk-writer.ts 98.49% <100.00%> (-0.30%) ⬇️
dev/src/index.ts 98.60% <100.00%> (-0.07%) ⬇️
dev/src/reference.ts 99.80% <100.00%> (-0.08%) ⬇️
dev/src/write-batch.ts 99.89% <100.00%> (-0.11%) ⬇️
dev/src/order.ts 98.09% <0.00%> (-1.15%) ⬇️
dev/src/pool.ts 97.75% <0.00%> (-0.90%) ⬇️
dev/src/transaction.ts 96.47% <0.00%> (-0.51%) ⬇️
dev/src/watch.ts 98.77% <0.00%> (-0.37%) ⬇️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ad6b923...c471b2d. Read the comment docs.

@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label May 22, 2020
dev/src/util.ts Outdated
export function wrapError(err: GoogleError, stack: string): Error {
const wrappedError = new GoogleError(err.message);
wrappedError.code = err.code;
wrappedError.stack += '\nCaused by: ' + stack;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we modify the stack in 'err' directly?

Copy link
Author

Choose a reason for hiding this comment

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

good point. done.

@thebrianchen thebrianchen added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label May 26, 2020
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label May 26, 2020
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

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

LGTM

@thebrianchen thebrianchen merged commit 7acdd7e into master May 27, 2020
@thebrianchen thebrianchen deleted the bc/error-stack branch May 27, 2020 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid argument error now explaining what the error is
4 participants