Skip to content

Commit

Permalink
fix: handle uncaught errors, support timeout attr (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Jul 26, 2023
1 parent 7e4d800 commit 5479d3a
Show file tree
Hide file tree
Showing 26 changed files with 302 additions and 11 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ Any variables to pass to the query.

The cache policy to use with this query request.

#### `timeout`

A time in milliseconds after which the query will be aborted and resolve to a timeout error.

#### `@then|results, revalidate|`

The content to display on query completion. The results object consists of:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div />
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
<div
id="GENERATED-1"
style="display:none"
>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
<div
id="GENERATED-0"
style="display:none"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
<div
id="GENERATED-1"
style="display:none"
>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
<div
id="GENERATED-0"
style="display:none"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
<div
id="GENERATED-1"
style="display:none"
>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
<div
id="GENERATED-0"
style="display:none"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div>
<noscript
id="GENERATED-0"
/>
</div>
<div
id="GENERATED-1"
style="display:none"
>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div>
<span>
TimeoutError: Timed out after 1ms
</span>
</div>
<div
id="GENERATED-0"
style="display:none"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { gql } from "../../../../../../index";
static const QUERY = gql`
query($name: String) {
hello(name: $name)
}
`;

class {
onCreate() {
this.state = { mounted: false }
}
onMount() {
this.state = { mounted: true }
}
}

<if(state.mounted)>
<gql-query query=QUERY variables={ name: "John" } timeout=1>
<@then|{ error }|><span>${error}</span></@then>
</gql-query>
</if>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Example</title>
<esbuild-assets/>
</head>
<body>
<gql-client url=input.graphqlURL />
<app />
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { gql } from "../../../../../../index";
static const QUERY = gql`
query($name: String) {
hello(name: $name)
}
`;
class {}

<gql-query query=QUERY variables={ name: "John" } timeout=1>
<@then|{ error }|><span>${error}</span></@then>
</gql-query>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Example</title>
<esbuild-assets/>
</head>
<body>
<gql-client url=input.graphqlURL />
<app />
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { gql } from "../../../../../../index";
static const QUERY = gql`
query($name: String) {
hello(name: $name)
}
`;

<gql-query query=QUERY variables={ name: "John" } timeout=1>
<@then|{ error }|><span>${error}</span></@then>
</gql-query>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Example</title>
<esbuild-assets/>
</head>
<body>
<gql-client url=input.graphqlURL />
<app />
</body>
</html>
13 changes: 13 additions & 0 deletions src/components/gql-query/__tests__/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ describe(
fixture(path.join(__dirname, "fixtures/client-only-variables"))
);

describe(
"client-only-timeout",
fixture(path.join(__dirname, "fixtures/client-only-timeout"))
);

describe("isomorphic", fixture(path.join(__dirname, "fixtures/isomorphic")));
describe(
"isomorphic-placeholder",
Expand All @@ -20,6 +25,10 @@ describe(
"isomorphic-variables",
fixture(path.join(__dirname, "fixtures/isomorphic-variables"))
);
describe(
"isomorphic-timeout",
fixture(path.join(__dirname, "fixtures/isomorphic-timeout"))
);

describe("server-only", fixture(path.join(__dirname, "fixtures/server-only")));
describe(
Expand All @@ -30,6 +39,10 @@ describe(
"server-only-variables",
fixture(path.join(__dirname, "fixtures/server-only-variables"))
);
describe(
"server-only-timeout",
fixture(path.join(__dirname, "fixtures/server-only-timeout"))
);

describe(
"update-variables",
Expand Down
82 changes: 72 additions & 10 deletions src/components/gql-query/components/gql-query-client/index.marko
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,75 @@ import { pipe, subscribe } from "wonka";
import { getClient, hydrateQuery } from "../../../../client";
import readyLookup from "../../ready-lookup";
class {
onCreate({ data, error, opKey }) {
this.state = { data, error, fetching: false };
onCreate(input) {
let { data, error, opKey } = input;
const state = { data, error, fetching: false };
this.mounted = false;
if (typeof document !== "undefined" && opKey) {
hydrateQuery(opKey, data, error);
readyLookup[this.id]();
if (typeof document === "undefined") {
this.isSSR = true;
if (error) {
input.toJSON = () => ({
...input,
error: {
_: true,
name: error.name,
message: error.message,
},
})
}
} else {
if (error && error._) {
state.error = new Error(error.message);
state.error.name = error.name;
error = state.error;
}
if (opKey) {
hydrateQuery(opKey, data, error);
}
const ready = readyLookup[this.id];
if (ready) {
this.isSSR = true;
ready();
} else {
this.isSSR = false;
}
}
this.state = state;
}
onInput(input) {
if (!input.opKey) {
this.once(this.mounted ? "update" : "mount", () => this.doQuery());
onInput() {
if (this.isSSR) {
this.isSSR = false;
return;
}
this.once(this.mounted ? "update" : "mount", () => this.doQuery());
}
onMount() {
this.mounted = true;
}
onDestroy() {
this.stopQuery();
this.stopTimeout();
}
stopQuery() {
this.unsubscribe && this.unsubscribe();
this.unsubscribe = undefined;
if (this.unsubscribe) {
this.unsubscribe();
this.unsubscribe = undefined;
}
}
stopTimeout() {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = undefined;
}
}
doQuery(options) {
this.stopTimeout();
this.stopQuery();
this.state.fetching = true;
this.unsubscribe = pipe(
Expand All @@ -35,11 +79,29 @@ class {
...options,
}),
subscribe(({ data, error }) => {
this.stopTimeout();
this.state.data = data;
this.state.error = error;
this.state.fetching = false;
})
).unsubscribe;
let timeout = this.input.timeout;
if (timeout == null) {
timeout = 10000;
}
if (timeout > 0) {
this.timeoutId = setTimeout(() => {
this.stopQuery();
const err = new Error("Timed out after " + timeout + "ms");
err.code = "ERR_AWAIT_TIMEDOUT";
err.name = "TimeoutError";
this.state.data = undefined;
this.state.error = err;
this.state.fetching = false;
}, timeout);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/components/gql-query/impl/browser.marko
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import readyLookup from "../ready-lookup";
query=input.query
variables=input.variables
requestPolicy=input.requestPolicy
timeout=input.timeout
then=input.then
placeholder=input.placeholder
/>
Expand Down
Loading

0 comments on commit 5479d3a

Please sign in to comment.