Day24 - 遇到 404 或 500 怎麽办,客制化错误页面

前言

在「错误捕捉、全域 CSS、共用 Layout,就用 _app.tsx 来搞定吧!」这边文章中有提到,目前在 Next.js 的 error boundary 无法捕捉到 SSR 发生的错误,会一律回 HTTP 500 给使用者,因此使用者会看到相对应的 500 画面。

而在 Next.js 客制化 404 与 500 的页面是很容易的一件事,就像是 App 与 Document 一样,都是在 pages/ 这个资料夹里面依照规范定义档案名称,就可以轻易地客制化这两个页面。

404 页面

可以透过 getStaticProps 在 SSG 阶段传入一些资料

要客制化 404 的页面必须在 pages/ 资料夹中新增一个档案为 404.tsx ,这个档案将会以 SSG 打包成静态的 HTML 档案:

// pages/404.tsx
const Custom404 = () => {
  return <div>Custom 404 page</div>;
};

export default Custom404;

如果一个 url 无法匹配 file-based routing 的机制,或是在 getStaticsPropsgetServerSideProps 回传 { notFound: true } ,服务器就会直接回传这个 404 的页面,不用再经过其他的运算。

500 页面

可以透过 getStaticProps 在 SSG 阶段传入一些资料

要客制化 500 的页面必须在 pages/ 资料夹中新增一个档案为 500.tsx ,这个档案将会以 SSG 打包成静态的 HTML 档案:

// pages/500.tsx
const Custom500 = () => {
  return <div>Custom 500 page</div>;
};

export default Custom500;

像是 getServerSideProps 在运行时发生错误,或是页面中发生错误都可能会造成 500,此时 Next.js 的服务器就会回传这个页面给使用者。

Error page

这个页面是用来处理除了 404 跟 500 以外的错误,而且同时包含客户端与服务器端错误。 React 的 error boundary - componentDidCatch 无法处理 SSR 发生的错误,但是在 Next.js 中可以经由这个档案来捕捉错误,并回传相对应的讯息给使用者。

虽然 error page 的作用跟 error boundary 很像,但是 error boundary 真正要做的事情是透过 **componentDidCatch 捕捉错误本身**,你可以对错误本身进行处理。然而在 error page 中假设遇到的是客户端的错误,实际上只是用来告诉使用者有错误,可是这样一定不能满足工程团队的需求,因为工程团队需要知道使用者实际上遇到的错误,所以需要使用 error boundary 来捕捉错误。

如此一来,在 Next.js 中其实可以考虑切分错误处理的职责,像是 error boundary 负责捕捉错误,并且纪录错误讯息至服务器,但是并不会处理显示的职责,而显示错误讯息则交给 error page,这样才不会让错误处理的职责散落程序码各处,也可以让後续维护的人更快速理解程序码的架构。

import { NextPageContext, NextPage } from "next";

interface ErrorProps {
  statusCode?: number;
}

const Error: NextPage<ErrorProps> = ({ statusCode }) => {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : "An error occurred on client"}
    </p>
  );
};

Error.getInitialProps = ({ res, err }: NextPageContext) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
  return { statusCode };
};

export default Error;

小结

404 跟 500 的客制化页面现在都是以 SSG 的方式打包成静态的 HTML 档案,可以免除 SSR 需要花时间渲染的成本。由於是 SSG,所以想要传入资料至 404 或 500 的页面中目前暂时做不到,有看到 GitHub discussion 有一篇在讲述希望可以提供这个功能,未来也许有一天能看到这个功能被实现。

在 Next.js 中除了能够客制化 404 跟 500 页面之外,也可以客制处理其他错误的页面,而且同时包含客户端与服务器端的错误。error page 的功用可以跟 error boundary 做切分,error page 处理显示页面,error boundary 处理拦截错误做进一步的处理,所以两者并不会相冲。

Reference


<<:  JavaScript Day 30. 关於 JavaScript 中的 This

>>:  Day 27 Inheritance

WordPress外挂总小小整理

详细可以参考这个网站页面的整理,下面是我协杠玩WordPress半年来的心得 https://109...

CMoney菁英软件工程师战斗营游戏专题开端_Week 5

一个月的光阴已过去 经过一个月的考试筛选 我们遗憾离开一位同学 但在此时 也展开游戏专题的序幕 我选...

[Golang]select 语句的分支选择规则-心智图总结

1. select语句的case表达式,都会在选择之前,先被求值。 2. case表达式,求值的顺序...

CLOUDWAYS主机限时6折优惠码,只到2021/12/1

优惠码BFCM2021 优惠时间:只到2021/12/01 折扣内容:首四个月6折(适用於所有方案)...

<Day23> 如何 更新 or 修改or 取消 委托单?

● 这章会示范如何更新及修改委托单 接续上一章 我们学会了如何下单 这章会示范怎麽去更新及修改已下好...