Skip to content

Commit

Permalink
actions: forward fetch rejections to the action handler (#49577)
Browse files Browse the repository at this point in the history
Pretty edge case-y but this PR fixes the case where a fetch error happens for an action and we want to handle at the action handler level.



link NEXT-1123
  • Loading branch information
feedthejim committed May 10, 2023
1 parent a7fd95e commit 958e34e
Showing 1 changed file with 49 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,54 +107,62 @@ export function serverActionReducer(
fetchServerAction(state, action)
)
}
try {
// suspends until the server action is resolved.
const { actionResult, actionFlightData, redirectLocation } =
readRecordValue(
action.mutable.inFlightServerAction!
) as Awaited<FetchServerActionResult>

// suspends until the server action is resolved.
const { actionResult, actionFlightData, redirectLocation } = readRecordValue(
action.mutable.inFlightServerAction!
) as Awaited<FetchServerActionResult>
if (redirectLocation) {
// the redirection might have a flight data associated with it, so we'll populate the cache with it
if (actionFlightData) {
const href = createHrefFromUrl(
redirectLocation,
// Ensures the hash is not part of the cache key as it does not affect fetching the server
false
)
state.prefetchCache.set(href, {
data: createRecordFromThenable(
Promise.resolve([
actionFlightData,
// TODO-APP: verify the logic around canonical URL overrides
undefined,
])
),
kind: PrefetchKind.TEMPORARY, //TODO-APP: maybe this could cached longer?
prefetchTime: Date.now(),
treeAtTimeOfPrefetch: action.mutable.previousTree!,
lastUsedTime: null,
})
}

if (redirectLocation) {
// the redirection might have a flight data associated with it, so we'll populate the cache with it
if (actionFlightData) {
const href = createHrefFromUrl(
redirectLocation,
// Ensures the hash is not part of the cache key as it does not affect fetching the server
false
// we throw the redirection in the action handler so that it is caught during render
action.reject(
getRedirectError(redirectLocation.toString(), RedirectType.push)
)
state.prefetchCache.set(href, {
data: createRecordFromThenable(
Promise.resolve([
} else {
// TODO-APP: populate the prefetch cache with the new flight data
if (actionFlightData) {
// this is an intentional hack around React: we want to update the tree in a new render
setTimeout(() => {
action.changeByServerResponse(
action.mutable.previousTree!,
actionFlightData,
// TODO-APP: verify the logic around canonical URL overrides
undefined,
])
),
kind: PrefetchKind.TEMPORARY, //TODO-APP: maybe this could cached longer?
prefetchTime: Date.now(),
treeAtTimeOfPrefetch: action.mutable.previousTree!,
lastUsedTime: null,
})
}
undefined
)
})
}

// we throw the redirection in the action handler so that it is caught during render
action.reject(
getRedirectError(redirectLocation.toString(), RedirectType.push)
)
} else {
// TODO-APP: populate the prefetch cache with the new flight data
if (actionFlightData) {
// this is an intentional hack around React: we want to update the tree in a new render
setTimeout(() => {
action.changeByServerResponse(
action.mutable.previousTree!,
actionFlightData,
// TODO-APP: verify the logic around canonical URL overrides
undefined
)
})
action.resolve(actionResult)
}
} catch (e: any) {
if (e.status === 'rejected') {
action.reject(e.value)
} else {
throw e
}

action.resolve(actionResult)
}

action.mutable.serverActionApplied = true
Expand Down

0 comments on commit 958e34e

Please sign in to comment.