Feature/62 error boundary #85
@@ -13,12 +13,24 @@ export interface ClientErrorReport {
|
|||||||
|
|
||||||
// Fire and forget, and deliberately swallowing — the one place in this change
|
// Fire and forget, and deliberately swallowing — the one place in this change
|
||||||
// where swallowing is correct. This runs inside componentDidCatch, so a
|
// where swallowing is correct. This runs inside componentDidCatch, so a
|
||||||
// reporter that rejected would throw from the very thing that exists to stop
|
// reporter that threw — or rejected — would throw from the very thing that
|
||||||
// throws, and there would be nothing left to catch it.
|
// exists to stop throws, and there would be nothing left to catch it.
|
||||||
|
//
|
||||||
|
// The try/catch guards the synchronous part: JSON.stringify(report) and the
|
||||||
|
// call to fetch() itself both run before any promise exists, so React does
|
||||||
|
// not guarantee componentDidCatch is handed a real Error — code can throw
|
||||||
|
// anything, and an object with a circular message or stack makes
|
||||||
|
// JSON.stringify throw. The .catch on the returned promise guards the async
|
||||||
|
// part, the rejection once fetch has actually started. Neither covers the
|
||||||
|
// other; both are required.
|
||||||
export function reportClientError(report: ClientErrorReport): void {
|
export function reportClientError(report: ClientErrorReport): void {
|
||||||
|
try {
|
||||||
void fetch('/api/client-errors', {
|
void fetch('/api/client-errors', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(report)
|
body: JSON.stringify(report)
|
||||||
}).catch(() => undefined);
|
}).catch(() => undefined);
|
||||||
|
} catch {
|
||||||
|
// Nothing to do — see the comment above.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user