elbywan / wretch

A tiny wrapper built around fetch with an intuitive syntax. :candy:
MIT License
4.83k stars 98 forks source link

Generic catcher #91

Closed evenfrost closed 4 years ago

evenfrost commented 4 years ago

Sorry in advance as it's not an issue and may be just a silly question, but I haven't found any info about how to catch generic errors with wretch instance. I'd like to have a handler, which will look something like this:

const api = wretch()
  .url('https://mysite.com')
  .catcher(err => console.log('we got an error', err);

and will catch any network error of any status code. I've tried to use .resolve(resolver => resolver.fetchError(err => console.log('err', err))), but with no success. Is there any way to accomplish this?

elbywan commented 4 years ago

Hi @evenfrost,

Is there any way to accomplish this?

Yes I think you could achieve this by using an undocumented feature (sorry about that 😉) to catch errors thrown by fetch:

const api = wretch('https://jsonplaceholder.typicode.com')
  // Errors thrown by Fetch (network errors) will be caught here.
  .catcher('__fromFetch', err => console.log('we got an error', err))
  // Status errors are thrown as plain Errors and will be caught here.
  .catcher('Error', err => console.log('we got an error', err.response.status, err.response.statusText))

// /posts/2931890418 returns a 404
api.url('/posts/2931890418').get().json(console.log)
// => we got an error 404 Not Found

// /posts/1 is valid
api.url('/posts/1').get().json(console.log)
// => Object { userId: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }
evenfrost commented 4 years ago

Working, thanks!

plee-fn commented 1 year ago

Hello @elbywan ,

It seems .catcher('__fromFetch', err => console.log('we got an error', err)) no longer works in v2.

const api = wretch('https://jsonplaceholder.typicode.com')
  // Errors thrown by Fetch (network errors) will be caught here.
  .catcher('__fromFetch', err => console.log('we got an error', err))
  // Status errors are thrown as plain Errors and will be caught here.
  .catcher('Error', err => console.log('we got an error', err.response.status, err.response.statusText))

In v1, __fromFetch was a string. However, in v2, it is now a Symbol. fetchError: cb => responseChain.error("__fromFetch", cb), https://github.com/elbywan/wretch/blob/v1/src/resolver.ts#L195

fetchError(cb) { return this.error(FETCH_ERROR, cb) }, https://github.com/elbywan/wretch/blob/master/src/resolver.ts#L108

export const FETCH_ERROR = Symbol() https://github.com/elbywan/wretch/blob/master/src/constants.ts#L3

How would I be able to simulate this behavior in v2?

heath-freenome commented 1 year ago

@elbywan does it make sense to export this FETCH_ERROR constant for use in this situation?

elbywan commented 1 year ago

How would I be able to simulate this behavior in v2?

Unless I'm mistaken, the FETCH_ERROR symbol is already exported from the wretch/constants file.

import { FETCH_ERROR } from "wretch/constants"

const api = wretch('htts://jsonplaceholder.typicode.com')
  // Replacing __fromFetch_ with FETCH_ERROR here should work
  .catcher(FETCH_ERROR, err => console.log('(FETCH_ERROR) we got an error', err))

Calling .resolve(r => r.fetchError(…) is also another less hacky way:

const api = wretch('htts://jsonplaceholder.typicode.com')
  .resolve(r => r.fetchError(err => console.log('(fetchError) we got an error', err)))
plee-fn commented 1 year ago

Thanks for the swift reply!

import { FETCH_ERROR } from "wretch/constants"

const api = wretch('htts://jsonplaceholder.typicode.com')
  // Replacing __fromFetch_ with FETCH_ERROR here should work
  .catcher(FETCH_ERROR, err => console.log('(FETCH_ERROR) we got an error', err))

Directly putting FETCH_ERROR into .catcher will lead to a typing error. Argument type unique symbol (for 'FETCH_ERROR' in constants.d.ts) is not assignable to parameter type number | string .catcher will probably need to be updated to handle the new type.

as for the second method

const api = wretch('htts://jsonplaceholder.typicode.com')
  .resolve(r => r.fetchError(err => console.log('(fetchError) we got an error', err)))

This works! Thanks for the help!