JavaScript 课程 · 第九章

报错处理与调试

代码出错不可怕,可怕的是不知道错在哪。这一章教你接住错误、看懂报错、一步步找到问题。

1这一章学什么

一句话目标:会用 try/catch 接住错误,会看懂三种最常见报错,会用 console.log 一步步定位问题。

学完这一章,脚本出错时你不会再干瞪眼:程序不会直接崩掉,你也能顺着报错信息找到出错的那一行。

2概念

① try / catch:给容易出错的代码兜个底

把「可能会出错」的代码放进 try(试一试)里;一旦出错,程序不会崩,而是跳进 catch(接住)里处理。

try {
  // 试着解析一段可能坏掉的文字
  const data = JSON.parse(maybeBrokenText);
} catch (e) {
  // 出错了会走到这里,e 就是这次错误
  console.log("解析失败:", e.message);
} finally {
  // 不管成功还是失败,最后都要执行的收尾(可选)
}

② console.log() 是你唯一的“眼睛”

脚本在后台跑,你看不见它肚子里的数据。console.log() 就是把变量“喊出来”给你看的唯一办法。

养成习惯:关键变量、关键分支都 log 出来。比如进入了哪个 if、拿到的原始数据是什么,都先打一行日志再说。

③ 三种最常见报错:先看最后一行和行号

报错信息通常很长,别慌:先看最后一行,再看它给的行号,那就是出错的位置。最常见的就这三种:

报错长这样是什么意思
xxx is not defined 变量没定义,或者“工具箱里没有这个东西”——名字写错了,或者忘了先声明。
Cannot read properties of undefined 在一个“空东西”(undefined)上取属性,比如 数据.名字,但数据本身是空的。可以用 ?. 防它:数据?.名字,数据是空的就直接返回空,不报错。
Unexpected token 多半是 JSON 格式坏了(少个引号、多个逗号),或者代码语法写错了。

④ 调试的正确顺序:先定位,再看数据

  1. 先确认代码跑到了哪一行:在几处关键位置逐步加 console.log,日志断在哪,问题就在哪附近。
  2. 再看那一行的数据长什么样:把变量整体打出来——console.log(JSON.stringify(变量, null, 2)),数据是空的、缺字段,一眼就看出来。
顺序别反:先定位、后改。没找到出错位置就动手改,越改越乱。

3动手试

下面三段代码都能真的运行。点「运行」,在下方看输出。

试一试 1:错误被接住,程序继续跑

try {
  JSON.parse("不是 JSON");  // 这段文字不是 JSON 格式,会出错
} catch (e) {
  console.log("解析失败:" + e.message);  // 错误被接住
}
console.log("程序没有崩,还在继续跑");
看:报错被接住,最后一行照样打印

试一试 2:访问没定义的东西

try {
  console.log(这个变量根本不存在);  // 没定义过,会出错
} catch (e) {
  console.log("出错了:" + e.message);  // 注意里面有 is not defined
}
看:报错原因里出现 is not defined

试一试 3:把变量整体打出来

// JSON.stringify 把对象变成带格式的文字,整体看清结构
console.log(JSON.stringify({ a: 1, b: [1, 2] }, null, 2));
调试时就这样把变量整个打出来检查

4练一练

点一个选项,立刻判对错。选错了会告诉你错在哪。

已答对 0 / 5 题

5适用案例

案例 1Surge 脚本改 JSON,必须 try/catch

Surge 脚本经常要改请求或响应的 JSON 内容。如果数据格式和预期不一样,JSON.parse 一出错脚本就停了,请求会被卡住。所以改 JSON 必须套 try/catch,而且出错也要调用 $done() 放行,别卡死人家的 App。

try {
  const obj = JSON.parse($response.body);  // 把响应内容转成对象
  obj.vip = true;                          // 改内容
  $done({ body: JSON.stringify(obj) });    // 改完放行
} catch (e) {
  console.log("改 JSON 失败:" + e.message);
  $done({});                               // 出错也放行,别卡住
}

案例 2Workers 出问题,先看日志

Worker 在云端跑,本地没法断点调试,出问题只能靠日志。在关键变量、关键分支都加上 console.log,然后去 CF 后台看日志(或 wrangler tail),顺着日志看数据走到哪一步变了样,问题基本就定位了。

console.log("收到的路径:", request.url);        // 关键变量
console.log("KV 里读到的原文:", raw);            // 原始数据
console.log("走进了未登录分支");                  // 关键分支

案例 3解析外部数据:先判断,再 parse

外部来的数据(接口返回、订阅内容、用户输入)随时可能是坏的。直接 JSON.parse 又不接住,一份坏数据就能让整个脚本崩。规矩是:先判断有没有内容,再 parse,并且套上 try/catch。

let data = null;
if (text) {                        // 先判断:有内容才解析
  try {
    data = JSON.parse(text);
  } catch (e) {
    console.log("外部数据是坏的:" + e.message);
  }
}
// data 是 null 就说明没拿到好数据,后面别硬用

小结:出错先别慌——用 try/catch 接住,用 console.log 找到出错的那一行,再看那一行的数据。