我正在为我的API调用编写一个助手,并且希望它能够
当调用为successful
text()响应,否则为完全响应,否则为这样做的原因是我有一个API调用的例子,其中期望有一个404,并且希望管理这个特定的情况。其他404 (在不同的调用中)确实是错误。
考虑下面的守则:
const apiCall = (url) => {
return fetch(url)
.then(r => {
if (r.ok) {
return r.text()
} else {
console.log('in apiCall → then(), fetch soft-failed, passing error downstream')
throw Error(r.statusText) // this works but is not what I want, I want to throw "r"
}
})
.catch(err => {
console.log('in apiCall → catch(), passing error downstream')
throw err
})
}
apiCall('http://httpstat.us/200')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err}`))
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err}`)) // this works but I obviously got a statusText and not an r
这输出
in apiCall → then(), fetch soft-failed, passing error downstream
in apiCall → catch(), passing error downstream
the return code was Error: Not Found
200 OK我希望做的是对一个期望404的调用(在上面的代码上下文中这是不正确的代码)。
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => {
if (err.Code == 404) {
// it is OK
} else {
// it is not OK
}
})对于任何非2xx响应不正确的另一个呼叫:
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => {
// not OK
})我怎样才能throw 的响应,而不仅仅是文本?
换句话说,我想要的代码:
const apiCall = (url) => {
return fetch(url)
.then(r => {
if (r.ok) {
return r.text()
} else {
console.log('in apiCall → then(), fetch soft-failed, passing error downstream')
throw r
}
})
.catch(err => {
console.log('in apiCall → catch(), passing error downstream')
throw err // I would need to manage actual errors (network, ...)
})
}
apiCall('http://httpstat.us/200')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err.Code}`))
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err.Code}`))
但这会输出undefined
in apiCall → then(), fetch soft-failed, passing error downstream
in apiCall → catch(), passing error downstream
the return code was undefined
200 OK发布于 2022-03-13 14:48:13
嗯,throwing r工作正常,您只是记录了错误的属性。状态代码可以通过r.status访问。
const apiCall = (url) => {
return fetch(url)
.then(r => {
if (r.ok) {
return r.text()
} else {
console.log('in apiCall → then(), fetch soft-failed, passing error downstream')
throw r
}
})
.catch(err => {
console.log('in apiCall → catch(), passing error downstream')
throw err // I would need to manage actual errors (network, ...)
})
}
apiCall('http://httpstat.us/200')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err.status}`))
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => console.log(`the return code was ${err.status}`))
这种方法的唯一问题是,您的代码不知道如何处理“硬错误”(代码中的网络错误或运行时错误)。您可以使用“鸭类型方法”(如果它具有status属性,它必须是响应对象.)来标识这些方法,但是更好的解决方案是有一个自定义错误类:
class HTTPError extends Error{
constructor(r){
super(`HTTP ${r.status} error`)
this.r = r
}
}
const apiCall = (url) => {
return fetch(url)
.then(r => {
if (r.ok) {
return r.text()
} else {
console.log('in apiCall → then(), fetch soft-failed, passing error downstream')
throw new HTTPError(r)
}
})
.catch(err => {
console.log('in apiCall → catch(), passing error downstream')
throw err
})
}
apiCall('http://httpstat.us/200')
.then(r => console.log(r))
.catch(err => {
if(!(err instanceof HTTPError))
throw err //Other error
console.log(`the return code was ${err.r.status}`)
})
apiCall('http://httpstat.us/404')
.then(r => console.log(r))
.catch(err => {
if(!(err instanceof HTTPError))
throw err //Other error
//You can access `r` via `err.r` here
console.log(`the return code was ${err.r.status}`)
})
发布于 2022-03-13 14:20:03
可以将参数添加为expectedFailureCodes,并在请求代码失败后进行检查。如果它是很好的期望,那么你可以处理它,你喜欢。
import fetch from "node-fetch";
const apiCall = (url, expectedFailureCodes=[]) => {
return fetch(url)
.then(async res => {
if (res.ok) return res
else if (expectedFailureCodes.includes(res.status)) {
return {
passedIntentionally: true,
res
}
}
else throw new Error(JSON.stringify({
status: res.status,
body: await res.text()
}))
})
.catch(err => {
throw err
})
}
apiCall("http://httpstat.us/404", [404]).then(res => {
console.log(res)
})
apiCall("http://httpstat.us/404", ).catch(err => {
console.log(err)
})
apiCall("http://httpstat.us/200", ).then(res => {
console.log(res)
})https://stackoverflow.com/questions/71457498
复制相似问题