`fetchNextData` error handling fails with TypeError: Attempted to assign to readonly property.
See original GitHub issueBug report
Describe the bug
I woke up this morning to find that some of our site’s CTA links (using ‘next/link’) were broken in mobile browsers, displaying “An unexpected error has occurred” to the user. The only thing I could find in Rollbar was this error: TypeError: Attempted to assign to readonly property.
.
Testing locally with iOS Simulator, I traced it to this line in .next/static/development/pages/_app.js
:
err.code = 'PAGE_LOAD_ERROR';
Here is the full function where the error is occurring:
function fetchNextData(pathname, query, isServerRender, cb) {
var attempts = isServerRender ? 3 : 1;
function getResponse() {
return fetch(utils_1.formatWithValidation({
// @ts-ignore __NEXT_DATA__
pathname: "/_next/data/".concat(__NEXT_DATA__.buildId).concat(pathname, ".json"),
query: query
}), {
// Cookies are required to be present for Next.js' SSG "Preview Mode".
// Cookies may also be required for `getServerSideProps`.
//
// > `fetch` won’t send cookies, unless you set the credentials init
// > option.
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
//
// > For maximum browser compatibility when it comes to sending &
// > receiving cookies, always supply the `credentials: 'same-origin'`
// > option instead of relying on the default.
// https://github.com/github/fetch#caveats
credentials: 'same-origin'
}).then(function (res) {
if (!res.ok) {
if (--attempts > 0 && res.status >= 500) {
return getResponse();
}
throw new Error("Failed to load static props");
}
return res.json();
});
}
return getResponse().then(function (data) {
return cb ? cb(data) : data;
})["catch"](function (err) {
// We should only trigger a server-side transition if this was caused
// on a client-side transition. Otherwise, we'd get into an infinite
// loop.
if (!isServerRender) {
err.code = 'PAGE_LOAD_ERROR';
}
throw err;
});
}
The page I am attempting to transition to is using getServerSideProps
to check the user’s a/b test cookie and redirect them based on the result:
export const getServerSideProps = async (ctx) => {
const expVariantId = getOrSetGoCookie(ctx);
if (expVariantId === '1') {
const { res, query } = ctx;
res
.writeHead(307, {
Location: `${process.env.HI_BASE_URL}/signup?${queryString.stringify(query)}`,
})
.end();
return { props: {} };
}
return { props: { expVariantId } };
};
This issue never occurs when navigating to the page directly or using a standard anchor tag - only when using ‘next/link’.
Here is the link for reference:
<Link href="/start" as={`${process.env.HI_BASE_URL}/start`} passHref>
<Button as="a" variant="green" width={1} mt={6} data-testid="GetStartedA">
Get Started
</Button>
</Link>
To Reproduce
Obviously, this is a sort of complicated example, and I’m not exactly sure what’s causing the initial error. Let me know if you need more information, and I can try to create an example repo when I’m able to.
Expected behavior
It would seem there are 2 issues here. One is that an error is occurring during when clicking a next/link
to a page using getServerSideProps
to redirect. The other is that during the handling of this error, another error is thrown when attempting to set the value of err.code
.
I would expect to get information about what the error is, if it’s something caused by my code, but we never make it that far.
Screenshots
If applicable, add screenshots to help explain your problem.
System information
- OS: iOS
- Browser: Safari (reported on Chrome too)
- Version of Next.js: 9.3.3
Additional context
Thank you! Again, happy to provide any more detail necessary.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:5
- Comments:10 (5 by maintainers)
This was fixed in
next@^9.5.2-canary.15
and newer. Please upgrade and let us know if it works for you!I actually switched to
getInitialProps
for other reasons, but the solution for the error that was causing this error was to stop using ‘next/link’/client-side routing. I have had so many issues with those links - especially on mobile devices. “An unexpected error has occurred”, links just plain doing nothing when you click them, etc.