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

feat: better error message when event listener is missing #656

Merged
merged 4 commits into from
Sep 24, 2018

Conversation

jye-sf
Copy link
Contributor

@jye-sf jye-sf commented Sep 18, 2018

Details

Provide a better error message when event listener is missing
Addresses #325

Does this PR introduce a breaking change?

  • Yes
  • No

If yes, please describe the impact and migration path for existing applications:
Please check if your PR fulfills the following requirements:

@jye-sf jye-sf added the nomerge label Sep 18, 2018
// TODO: Figure out where to catch the real thrown event
expect(() => {
element.triggerFoo();
}).toThrow("Event listener for event 'foo' was not found.");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does anyone have any suggestions for where to catch this exception?

Although the exception is thrown directly after triggering the event handler, something in the engine delays the exception from reaching the test until much later, leading to an uncaught exception.

if (process.env.NODE_ENV !== 'production') {
throw new ReferenceError(`Event listener for event '${event.type}' was not found.`);
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this the right place for performing this check? I saw a few other potential places, but this seemed to align closest with existing behavior. The other options I saw were:

  • The handler is generated when the engine loads. We're able to throw an error when we bind the handler itself at '$api_b'.
  • The other suggestion was to provide a warning/error during compilation, but I couldn't find a good place where we knew both the binding on the template and the full list of functions on the component.

Copy link
Contributor

Choose a reason for hiding this comment

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

this will swallow the error in production, which is not a good thing. I will propose this:

        if (process.env.NODE_ENV !== 'production') {
            assert.isTrue(isFunction(fn), `Event listener for event '${event.type}' was not found.`);
        }
        callHook(thisValue, fn, [event]);

In this case, it doesn't introduce an extra if condition in prod, the check happens before the invocation.

Another problem here is that in order to see that error, the event must be dispatched. This itself makes is hard to give early errors. I think there are other places where this might be more useful, e.g.: api.b could do that assertion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

api.b could do the assertion earlier, but we wouldn't be able to provide any meaningful context for the error if we do it there because the event and event type are only provided to api.b when the dispatch happens.

We could enhance api.b to have that context, and the compiler to provide it.

// component
on: {
    "foo": api_bind(__getKey$3($cmp, "foo"), "foo")
}

// engine
export function b(fn: EventListener, fnName: string) {
    ...
    if (process.env.NODE_ENV !== 'production') {
        assert.isTrue(isFunction(fn), `Event listener '${fnName}' was not found.`);
    }
    ...
}

We can now reference the listener by name, but we're also passing an extra parameter for the sole purpose of a DEV mode error message.

Copy link
Contributor

Choose a reason for hiding this comment

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

I can see two path forward here:

  • Let the bind method to receive only the fnName, and we can resolve the method based on the current vm being rendered.
export function b(fnName: string): EventListener {
    if (isNull(vmBeingRendered)) {
        throw new Error();
    }
    const vm: VM = vmBeingRendered;
    const fn = vm.component[fnName];
    if (process.env.NODE_ENV !== 'production') {
        assert.isTrue(isFunction(fn), `Event listener '${fnName}' was not found on ${vm}.`);
    }
    return function(event: Event) {
        if (vm.fallback) {
            patchEvent(event);
        }
        invokeEventListener(vm, fn, vm.component, event);
    };
}

In any case, this is cached by the compiler, so, no much of a problem here.

  1. compiler does all the work, since it will cache those bindings, it could throw.

This is more complicated because throw is not allowed in expressions like the ternary operator that we use today for caching purposes.

I will favor 1, as it will tell you very clearly, what is the binding that you are using from the template that does not exist on the instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we're able to resolve the fnName from the VM, let's do that then. Like you said, it's clearer, and it's also more easily testable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Resolving the method from the method name works for listeners bound to the component, but isn't able to deal with listeners bound to some other data structure. The most common scenario is when when using an iterator.

// component
api_iterator(__getKey$3($cmp, "list"), function(item) {
...
on: {
    // item is specific to this scope
    "foo": api_bind(__getKey$3(item, "foo"))
}
...
})

We could pass the scope for the binding down (api_bind("foo", item) or api_bind("foo", $cmp)), but that greatly increases the complexity of api.b, and doesn't seem much better than just resolving the function first then passing the function name down with it.

For the second path you mentioned, where does the compiler cache the bindings? I see where we generate the code to memoize the handlers when they're bound to the component instance, but not where we're cross referencing the bindings on the template with the component instance to cache the bindings themselves.

Copy link
Contributor

Choose a reason for hiding this comment

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

jaja! bad bad bad memory! It is my fault, I designed the api.b a while ago, I should have remembered that limitation. <a onclick={foo.bar.baz}>.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's go with the original proposal, it is a limited solution, but covers a good portion. Make sure that you look at my first comment on how to make it more performant.

@jye-sf jye-sf requested a review from caridy September 18, 2018 22:05
@salesforce-best-lwc-internal
Copy link

Benchmark results

Base commit: 2b1dac4 | Target commit: 9c4b78a

lwc-engine-benchmark-ie11

table-append-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/append/1k duration 898.00 (±0.00 ms) 884.60 (±0.00 ms) -13.4ms (1.5%) 👌
table-clear-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/clear/1k duration 89.60 (±0.00 ms) 83.60 (±0.00 ms) -6.0ms (6.7%) 👌
table-create-10k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/create/10k duration 8563.70 (±0.00 ms) 8333.90 (±0.00 ms) -229.8ms (2.7%) 👌
table-create-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/create/1k duration 750.20 (±0.00 ms) 738.50 (±0.00 ms) -11.7ms (1.6%) 👌
table-update-10th-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/update-10th/1k duration 125.90 (±0.00 ms) 128.30 (±0.00 ms) +2.4ms (1.9%) 👌
tablecmp-append-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/append/1k duration 1553.40 (±0.00 ms) 1548.40 (±0.00 ms) -5.0ms (0.3%) 👌
tablecmp-clear-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/clear/1k duration 145.30 (±0.00 ms) 145.80 (±0.00 ms) +0.5ms (0.3%) 👌
tablecmp-create-10k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/create/10k duration 17875.10 (±0.00 ms) 17709.50 (±0.00 ms) -165.6ms (0.9%) 👌
tablecmp-create-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/create/1k duration 1399.60 (±0.00 ms) 1424.40 (±0.00 ms) +24.8ms (1.8%) 👌
tablecmp-update-10th-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/update-10th/1k duration 111.50 (±0.00 ms) 105.00 (±0.00 ms) -6.5ms (5.8%) 👌

lwc-engine-benchmark

table-append-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/append/1k duration 161.95 (±5.30 ms) 170.50 (±4.00 ms) +8.6ms (5.3%) 👎
table-clear-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/clear/1k duration 13.60 (±0.80 ms) 14.05 (±0.85 ms) +0.5ms (3.3%) 👌
table-create-10k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/create/10k duration 928.85 (±10.60 ms) 945.15 (±6.75 ms) +16.3ms (1.8%) 👎
table-create-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/create/1k duration 112.00 (±2.25 ms) 116.10 (±2.60 ms) +4.1ms (3.7%) 👎
table-update-10th-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table/update-10th/1k duration 98.50 (±3.70 ms) 101.30 (±4.45 ms) +2.8ms (2.8%) 👎
tablecmp-append-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/append/1k duration 235.55 (±7.65 ms) 251.50 (±4.95 ms) +15.9ms (6.8%) 👎
tablecmp-clear-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/clear/1k duration 20.45 (±2.30 ms) 22.80 (±2.20 ms) +2.4ms (11.5%) 👎
tablecmp-create-10k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/create/10k duration 1663.35 (±16.75 ms) 1678.15 (±14.80 ms) +14.8ms (0.9%) 👎
tablecmp-create-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/create/1k duration 186.40 (±5.10 ms) 194.75 (±5.50 ms) +8.4ms (4.5%) 👎
tablecmp-update-10th-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-component/update-10th/1k duration 82.95 (±6.25 ms) 86.30 (±5.55 ms) +3.4ms (4.0%) 👌
wc-append-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-wc/append/1k duration 273.20 (±14.60 ms) 275.05 (±20.45 ms) +1.8ms (0.7%) 👎
wc-clear-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-wc/clear/1k duration 29.85 (±2.50 ms) 32.05 (±2.45 ms) +2.2ms (7.4%) 👎
wc-create-10k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-wc/create/10k duration 2165.55 (±16.60 ms) 2199.05 (±16.00 ms) +33.5ms (1.5%) 👎
wc-create-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-wc/create/1k duration 229.25 (±6.75 ms) 235.05 (±5.65 ms) +5.8ms (2.5%) 👎
wc-update-10th-1k metric base(2b1dac4) target(9c4b78a) trend
benchmark-table-wc/update-10th/1k duration 86.80 (±4.85 ms) 91.65 (±6.15 ms) +4.8ms (5.6%) 👎

Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

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

Need more thoughts.

packages/lwc-engine/src/framework/__tests__/events.spec.ts Outdated Show resolved Hide resolved
@@ -125,7 +125,13 @@ export function invokeEventListener(vm: VM, fn: EventListener, thisValue: undefi
establishContext(context);
let error;
try {
callHook(thisValue, fn, [event]);
if (fn) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we check if 'thisValue' exists since its type can be undefined?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

callHook(thisValue, fn, [event]);
} else {
if (process.env.NODE_ENV !== 'production') {
throw new ReferenceError(`Event listener for event '${event.type}' was not found.`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should the message say 'handler' instead? I can see the wording being more intuitive since the devs won't manually attach listeners but specify an even handler in their template, which can make the error message more obvious.

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 went with 'listener' since that's the wording we used in our docs: http://lwc.sfdc.es/guide/events.html#Attach-a-Listener-Declaratively.

We do also use 'handler' in the same section of the doc though; do we have a consistent wording for 'listener' vs 'handler'?

@salesforce-best-lwc-internal
Copy link

Benchmark results

Base commit: ee1e513 | Target commit: 81378e1

lwc-engine-benchmark-ie11

table-append-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/append/1k duration 879.50 (±0.00 ms) 902.50 (±0.00 ms) +23.0ms (2.6%) 👌
table-clear-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/clear/1k duration 79.90 (±0.00 ms) 79.10 (±0.00 ms) -0.8ms (1.0%) 👌
table-create-10k metric base(ee1e513) target(81378e1) trend
benchmark-table/create/10k duration 8253.80 (±0.00 ms) 8592.80 (±0.00 ms) +339.0ms (4.1%) 👌
table-create-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/create/1k duration 727.90 (±0.00 ms) 745.70 (±0.00 ms) +17.8ms (2.4%) 👌
table-update-10th-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/update-10th/1k duration 124.50 (±0.00 ms) 137.80 (±0.00 ms) +13.3ms (10.7%) 👌
tablecmp-append-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/append/1k duration 1542.00 (±0.00 ms) 1547.80 (±0.00 ms) +5.8ms (0.4%) 👌
tablecmp-clear-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/clear/1k duration 144.80 (±0.00 ms) 151.70 (±0.00 ms) +6.9ms (4.8%) 👌
tablecmp-create-10k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/create/10k duration 15996.30 (±0.00 ms) 15955.70 (±0.00 ms) -40.6ms (0.3%) 👌
tablecmp-create-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/create/1k duration 1390.50 (±0.00 ms) 1421.80 (±0.00 ms) +31.3ms (2.3%) 👌
tablecmp-update-10th-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/update-10th/1k duration 104.70 (±0.00 ms) 109.40 (±0.00 ms) +4.7ms (4.5%) 👌

lwc-engine-benchmark

table-append-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/append/1k duration 161.45 (±4.75 ms) 168.25 (±16.10 ms) +6.8ms (4.2%) 👎
table-clear-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/clear/1k duration 12.55 (±0.70 ms) 13.60 (±0.80 ms) +1.0ms (8.4%) 👎
table-create-10k metric base(ee1e513) target(81378e1) trend
benchmark-table/create/10k duration 924.15 (±6.65 ms) 1025.95 (±69.70 ms) +101.8ms (11.0%) 👎
table-create-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/create/1k duration 111.95 (±2.15 ms) 127.45 (±18.45 ms) +15.5ms (13.8%) 👎
table-update-10th-1k metric base(ee1e513) target(81378e1) trend
benchmark-table/update-10th/1k duration 87.80 (±3.30 ms) 102.45 (±5.40 ms) +14.6ms (16.7%) 👎
tablecmp-append-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/append/1k duration 241.75 (±9.10 ms) 257.95 (±24.15 ms) +16.2ms (6.7%) 👎
tablecmp-clear-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/clear/1k duration 20.60 (±2.60 ms) 21.70 (±2.25 ms) +1.1ms (5.3%) 👎
tablecmp-create-10k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/create/10k duration 1667.65 (±11.55 ms) 1915.75 (±122.25 ms) +248.1ms (14.9%) 👎
tablecmp-create-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/create/1k duration 184.55 (±5.35 ms) 194.80 (±12.30 ms) +10.3ms (5.6%) 👎
tablecmp-update-10th-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-component/update-10th/1k duration 84.85 (±4.85 ms) 94.65 (±15.00 ms) +9.8ms (11.5%) 👎
wc-append-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-wc/append/1k duration 274.20 (±14.70 ms) 316.95 (±53.90 ms) +42.8ms (15.6%) 👎
wc-clear-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-wc/clear/1k duration 30.00 (±2.35 ms) 34.45 (±5.05 ms) +4.5ms (14.8%) 👎
wc-create-10k metric base(ee1e513) target(81378e1) trend
benchmark-table-wc/create/10k duration 2149.10 (±16.55 ms) 2391.00 (±140.90 ms) +241.9ms (11.3%) 👎
wc-create-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-wc/create/1k duration 232.50 (±6.25 ms) 254.00 (±30.10 ms) +21.5ms (9.2%) 👎
wc-update-10th-1k metric base(ee1e513) target(81378e1) trend
benchmark-table-wc/update-10th/1k duration 86.70 (±5.95 ms) 93.35 (±8.50 ms) +6.6ms (7.7%) 👎

@@ -125,6 +125,9 @@ export function invokeEventListener(vm: VM, fn: EventListener, thisValue: undefi
establishContext(context);
let error;
try {
if (process.env.NODE_ENV !== 'production') {
assert.isTrue(isFunction(fn), `Event listener for event '${event.type}' was not found.`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably change this error to be more specific, something like: Invalid event handler for event 'foo' in ${vm} so they at least know what this is, and where it is happening.

Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

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

almost ready, let's provide more information and a more clear message.

@salesforce-best-lwc-internal
Copy link

Benchmark results

Base commit: e971f2c | Target commit: 9da34f1

lwc-engine-benchmark-ie11

table-append-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/append/1k duration 801.80 (±0.00 ms) 872.90 (±0.00 ms) +71.1ms (8.9%) 👌
table-clear-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/clear/1k duration 78.50 (±0.00 ms) 109.20 (±0.00 ms) +30.7ms (39.1%) 👌
table-create-10k metric base(e971f2c) target(9da34f1) trend
benchmark-table/create/10k duration 7377.80 (±0.00 ms) 8344.40 (±0.00 ms) +966.6ms (13.1%) 👌
table-create-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/create/1k duration 673.80 (±0.00 ms) 702.40 (±0.00 ms) +28.6ms (4.2%) 👌
table-update-10th-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/update-10th/1k duration 114.80 (±0.00 ms) 136.70 (±0.00 ms) +21.9ms (19.1%) 👌
tablecmp-append-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/append/1k duration 1049.80 (±0.00 ms) 1512.60 (±0.00 ms) +462.8ms (44.1%) 👌
tablecmp-clear-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/clear/1k duration 191.20 (±0.00 ms) 144.70 (±0.00 ms) -46.5ms (24.3%) 👌
tablecmp-create-10k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/create/10k duration 10701.20 (±0.00 ms) 15857.30 (±0.00 ms) +5156.1ms (48.2%) 👌
tablecmp-create-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/create/1k duration 968.40 (±0.00 ms) 1382.70 (±0.00 ms) +414.3ms (42.8%) 👌
tablecmp-update-10th-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/update-10th/1k duration 104.90 (±0.00 ms) 108.30 (±0.00 ms) +3.4ms (3.2%) 👌

lwc-engine-benchmark

table-append-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/append/1k duration 161.30 (±5.10 ms) 164.60 (±5.60 ms) +3.3ms (2.0%) 👎
table-clear-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/clear/1k duration 12.25 (±0.75 ms) 13.00 (±0.65 ms) +0.8ms (6.1%) 👎
table-create-10k metric base(e971f2c) target(9da34f1) trend
benchmark-table/create/10k duration 929.75 (±9.60 ms) 942.45 (±6.85 ms) +12.7ms (1.4%) 👎
table-create-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/create/1k duration 110.20 (±3.10 ms) 113.05 (±2.80 ms) +2.9ms (2.6%) 👎
table-update-10th-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table/update-10th/1k duration 98.45 (±2.70 ms) 86.75 (±1.95 ms) -11.7ms (11.9%) 👍
tablecmp-append-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/append/1k duration 240.95 (±6.55 ms) 242.95 (±8.15 ms) +2.0ms (0.8%) 👌
tablecmp-clear-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/clear/1k duration 19.85 (±2.00 ms) 20.80 (±2.30 ms) +0.9ms (4.8%) 👌
tablecmp-create-10k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/create/10k duration 1659.95 (±11.85 ms) 1689.85 (±11.95 ms) +29.9ms (1.8%) 👎
tablecmp-create-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/create/1k duration 187.05 (±4.50 ms) 188.50 (±7.30 ms) +1.4ms (0.8%) 👌
tablecmp-update-10th-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-component/update-10th/1k duration 82.20 (±7.20 ms) 83.25 (±7.30 ms) +1.1ms (1.3%) 👌
wc-append-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-wc/append/1k duration 264.15 (±18.90 ms) 266.95 (±17.70 ms) +2.8ms (1.1%) 👌
wc-clear-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-wc/clear/1k duration 31.95 (±2.65 ms) 30.35 (±1.60 ms) -1.6ms (5.0%) 👌
wc-create-10k metric base(e971f2c) target(9da34f1) trend
benchmark-table-wc/create/10k duration 2153.30 (±9.40 ms) 2156.95 (±9.70 ms) +3.6ms (0.2%) 👌
wc-create-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-wc/create/1k duration 224.85 (±6.00 ms) 231.55 (±5.60 ms) +6.7ms (3.0%) 👎
wc-update-10th-1k metric base(e971f2c) target(9da34f1) trend
benchmark-table-wc/update-10th/1k duration 84.40 (±4.80 ms) 88.25 (±4.90 ms) +3.8ms (4.6%) 👎

@jye-sf jye-sf merged commit e77f7a7 into master Sep 24, 2018
@caridy caridy deleted the jye/missing-handler-error branch September 24, 2018 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants