Skip to content

Commit 2423224

Browse files
authored
Merge pull request #22 from ilyalesik/improve-fetch-error
Improving useFetch error
2 parents c22bff9 + 06d7d06 commit 2423224

File tree

6 files changed

+68
-7
lines changed

6 files changed

+68
-7
lines changed

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
React hook for conveniently use Fetch API.
88

9-
* **Tiny** (408 B). Calculated by [size-limit](https://github.com/ai/size-limit)
9+
* **Tiny** (556 B). Calculated by [size-limit](https://github.com/ai/size-limit)
1010
* Both **Flow** and **TypeScript** types included
1111

1212
```javascript
@@ -54,6 +54,30 @@ const { isLoading, data } = useFetch("https://swapi.co/api/people/1", {
5454

5555
```
5656

57+
### Error handling
58+
59+
The `useFetch` hook returns an `error` field at any fetch exception.
60+
The `error` field extends [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
61+
and has `status` and `statusText` fields equal to [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
62+
63+
```javascript
64+
...
65+
66+
const Component = () => {
67+
const { isLoading, data, error } = useFetch("https://swapi.co/api/people/1");
68+
69+
if (error) {
70+
return <div>
71+
<p>Code: ${error.status}</p>
72+
<p>Message: ${error.statusText}</p>
73+
</div>
74+
}
75+
76+
...
77+
};
78+
79+
```
80+
5781
### Multiple requests
5882
Multiple `useFetch` in the same file/component supported:
5983

examples/basic/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import useFetch from "../../index";
44

55

66
const App = () => {
7-
const {isLoading, data} = useFetch(`https://swapi.co/api/people/1`);
7+
const {isLoading, data, error} = useFetch(`https://swapi.co/api/people/1`);
88

9-
console.log(isLoading, data);
9+
console.log(isLoading, data, error && error.status);
1010

1111
return <div>
1212
<p>isLoading: {isLoading && "true" || "false"}</p>

index.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11

22
declare namespace useFetch {
3+
export interface UseFetchError extends Error {
4+
status: number,
5+
statusText: string
6+
}
7+
38
export interface FetchResult<T> {
49
data?: T,
510
isLoading: boolean,
6-
error?: any
11+
error?: UseFetchError
712
}
813

914
export interface HookOptions extends RequestInit {

index.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
var usePromise = require('./usePromise')
22

3+
function UseFetchError (status, statusText, message, fileName, lineNumber) {
4+
var instance = new Error(message, fileName, lineNumber)
5+
instance.name = 'UseFetchError'
6+
instance.status = status
7+
instance.statusText = statusText
8+
Object.setPrototypeOf(instance, Object.getPrototypeOf(this))
9+
if (Error.captureStackTrace) {
10+
Error.captureStackTrace(instance, UseFetchError)
11+
}
12+
return instance
13+
}
14+
15+
UseFetchError.prototype = Object.create(Error.prototype, {
16+
constructor: {
17+
value: Error,
18+
enumerable: false,
19+
writable: true,
20+
configurable: true
21+
}
22+
})
23+
24+
Object.setPrototypeOf(UseFetchError, Error)
25+
326
function useFetch (
427
path,
528
options,
@@ -11,7 +34,13 @@ function useFetch (
1134
return usePromise(!blocked && function (p, o, s) {
1235
return fetch(p, o)
1336
.then((s && s.formatter) || (o && o.formatter) || function (response) {
14-
if (!response.ok) throw Error(response.statusText)
37+
if (!response.ok) {
38+
throw new UseFetchError(
39+
response.status,
40+
response.statusText,
41+
'Fetch error'
42+
)
43+
}
1544
return response.json()
1645
})
1746
},

index.js.flow

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
type TUseFetchResult<T> = {
44
data: ?T,
55
isLoading: boolean,
6-
error: mixed,
6+
error?: Error & {
7+
status: number,
8+
statusText: string
9+
}
710
};
811
declare function useFetch<T>(path: RequestInfo, options?: { ...RequestOptions,
912
formatter?: (Response) => Promise<T>,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"ignore": [
3131
"react"
3232
],
33-
"limit": "408 B",
33+
"limit": "556 B",
3434
"path": "index.js",
3535
"running": false
3636
}

0 commit comments

Comments
 (0)