Я создаю приложение Next.js, обслуживаемое сервером Node (Express), который извлекает данные посредством запросов к API. Я храню конечные точки моего запроса в отдельном api
файле:
const apiBase = 'http://www.example.com'
export default {
news: apiBase + '/news/'
// other endpoints
}
Затем я выполняю свои запросы в getInitialProps
и выполняю условный рендеринг в зависимости от того, выдал ли запрос ошибку или нет:
static async getInitialProps( { query: { slug } } ) {
const news = await asyncReq( api.news + slug )
return { news, error: news.status }
}
render() {
return this.props.error ? <Error /> : <News />
}
asyncReq
- это вспомогательная функция, которая выглядит следующим образом:
export const asyncReq = endpoint => {
return
fetch( endpoint )
.then( res => { return res.ok ? res.json() : res } )
}
Все это прекрасно работает как при успешном запросе, так и при получении ошибок 404
или 500
. Но предположим, что я намеренно использовал неверную конечную точку:
const apiBase = 'http://www.example.com'
export default {
news: wrongApiBase + '/news/'
// other endpoints
}
В этом случае Node выдает мне следующую ошибку, поскольку wrongApiBase
не определено:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 498)
это то, что он должен делать, но ошибка приводит к тому, что страница никогда не загружается. Что я должен сделать, чтобы справиться с ошибкой? Моя идея заключалась в том, чтобы связать оператор catch
с asyncReq
, но я не уверен, что мне следует возвращать из него, чтобы потом использовать в getInitialProps
. Я попытался вернуть false
, но ничего не изменилось, страница просто не загружается.
export const asyncReq = endpoint => {
return
fetch( endpoint )
.then( res => { return res.ok ? res.json() : res } )
.catch( err => { // What should I return here? )
}
+++ ОБНОВЛЕНИЕ +++
Как оказалось, возникла проблема с ошибкой, которую я выдал. Как я уже сказал, я использовал неправильное имя переменной (wrongBaseApi
), чтобы вызвать ошибку, из-за которой Node никогда не обслуживал страницу. Оглядываясь назад, это имеет смысл, поскольку это ошибка с кодом узла, а не с входящим запросом.
Используя правильную переменную, но присвоив ей неправильное значение (фактически неверная база API, такая как http://dahfjkdahfds.com
, что является не ошибкой узла, а ошибкой запроса), я смог найти решение: используя блок try / catch, предлагаемый @iKoala и @DEVCNN work. Итак, мой код стал:
static async getInitialProps( { query: { slug } } ) {
const news = await asyncReq( api.news + slug )
return { news }
}
render() {
// this.props.news.data
// this.props.news.error
}
и
export async function asyncReq( endpoint ) {
try {
const res = await fetch( endpoint )
return {
data: res.ok ? await res.json().then( val => { return val } ) : null,
error: res.ok ? false : res.status
}
} catch( error ) {
return { error }
}
}