跳至主要內容
產品桌面工具TASTECAD圖面檢視TASTEFILES檔案管理TASTEFTP檔案傳輸TASTESSH遠端工作空間TASTEZIP壓縮與解壓縮開發工具TASTECODERust 整合開發環境TASTESTUDIO整合開發與測試環境TASTEETL資料整合(ETL)伺服器TASTEREMOTE遠端桌面伺服器TASTEGEO空間資訊伺服器TASTEMAIL郵件工作空間開始使用下載文件購買所有產品
市集
資訊
技術資訊今日開發資訊開發文件程式語言RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartWeb 前端框架Next.jsReactVue.js · NuxtSvelteKitAngular伺服器框架Spring BootDjangoFastAPIASP.NET CoreNestJS · Express應用程式與桌面框架TauriFlutterReact NativeElectron演算法演算法基礎核心演算法進階演算法實務演算法
社群專案開發日誌提示詞AI 工具問題作品展示社群指南
合作技術傳授網站建置桌面應用程式建置發布與付款流程銷售合作夥伴聯絡我們
服務遠端桌面安裝包客製
TASTEDEV
產品

桌面工具

TASTECAD再複雜的圖面,也能輕鬆開啟TASTEFILES只挑需要的檔案,最快送達TASTEFTP讓檔案往來,走最俐落的路TASTESSH在你與伺服器之間,築起更穩固的連線TASTEZIP壓得更快,解得更安心

開發工具

TASTECODE在一個視窗中完成 Rust 應用程式的編輯、建置、偵錯與測試TASTESTUDIO從編輯到遠端測試,再到經核准的 AI 修正TASTEETL邊看數值,邊搬資料

伺服器

TASTEREMOTE在自己的伺服器上運行的遠端桌面TASTEGEO以 Rust 重新打造相容 GeoServer 的空間資訊伺服器TASTEMAIL把郵件的主導權拿回自己手上

開始使用

下載所有產品的最新版本文件各產品使用方法購買訂閱與永久授權所有產品一覽全部產品
所有產品
市集資訊
技術

資訊

今日開發資訊語言、框架、GitHub 與 AI 官方發布開發文件語言、框架與演算法指南

程式語言

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

框架

Web 前端框架Next.jsReactVue.js · NuxtSvelteKitAngular
伺服器框架Spring BootDjangoFastAPIASP.NET CoreNestJS · Express
應用程式與桌面框架TauriFlutterReact NativeElectron

演算法

演算法基礎複雜度分析 · 排序 · 搜尋 · 基礎資料結構 · 樹與堆積核心演算法圖形走訪 · 最短路徑與最小生成樹 · 動態規劃 · 貪婪演算法 · 分治法 · 回溯法進階演算法字串演算法 · 數學與數論 · 位元運算 · 線段樹 · 併查集實務演算法程式面試解題策略 · LRU 快取 · 速率限制 · 一致性雜湊
查看全部開發文件
社群
專案探索開發者與作品開發日誌決策與試錯提示詞可重複使用的指令AI 工具問題Claude、Codex、Gemini 的問題與替代做法作品展示已完成的成果社群指南我們如何公開打造
合作
技術傳授用 Rust 與 egui 打造原生應用程式網站建置10 種語言、帳號、文件與下載桌面應用程式建置Rust 與 egui,不用 WebView發布與付款流程簽章、MSI、deb、rpm、AppImage、雜湊銷售合作夥伴推薦即得 30%聯絡我們開發、合作與投資諮詢
服務
遠端桌面用瀏覽器連線你的電腦安裝包客製只裝需要的,設定預先放好
購買
繁
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
登入
登入
TASTEDEV

從小工具到更好的開發。

support@tastedev.net支持 TASTEDEV
產品產品系列購買文件下載市集客戶支援
社群專案開發日誌提示詞AI 工具問題作品展示
政策隱私權政策服務條款訂閱條款退款政策社群規範
帳戶登入註冊
訪客
今天
012345678901234567890123456789012345678901234567890123456789
昨天
012345678901234567890123456789012345678901234567890123456789
累計瀏覽
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
公司名稱
GXSOFT
負責人
CHOI YOUNG GU
營業登記號碼
853-44-00368
地址
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
電話
+82-10-4404-1523
電子郵件
whitecalvin@tastedev.net
個人資料保護負責人
CHOI YOUNG GU

© 2026 TASTEDEV產品資訊以經驗證的開發原始碼為準。已發布·持續改進

JavaScript 文件
JavaScript
Getting StartedSyntax BasicsTypes and DataModules and PackagesErrors and TestingKey Concepts: Async and Closures
討論

JavaScript 指南 · 5/6

Errors and Testing

本章目前僅提供英文版。

Sooner or later every program meets bad input, a dropped connection or a missing file. This chapter covers throwing and catching errors, the built-in error types, custom errors, error handling in async code, and testing with the runner built into Node.js.

throw, try, catch and finally

Signal a problem with throw and handle it with try...catch. A finally block runs whether or not anything failed, which makes it the right place for cleanup. Always throw Error objects rather than strings: they carry a stack that tells you where things went wrong.

function parseAge(input) {
  const age = Number(input);
  if (!Number.isInteger(age) || age < 0) {
    throw new RangeError(`Not a valid age: ${input}`);
  }
  return age;
}

try {
  console.log(parseAge("29")); // 29
  console.log(parseAge("-3")); // throws here
  console.log("never reached");
} catch (error) {
  console.error(error.name, error.message); // RangeError Not a valid age: -3
} finally {
  console.log("done checking");
}

Built-in error types

The engine and built-in functions throw different subclasses of Error, which you can tell apart with instanceof.

TypeTypical cause
TypeErrorReading a property of undefined, calling a non-function
ReferenceErrorUsing a variable that was never declared
RangeErrorA value outside the allowed range, e.g. new Array(-1)
SyntaxErrorInvalid code, or bad input to JSON.parse

Custom errors and cause

Application-specific failures are easier to handle as subclasses of Error. When you catch one error and throw another, pass the original as cause so the root problem is not lost.

class NotFoundError extends Error {
  constructor(resource, options) {
    super(`${resource} not found`, options);
    this.name = "NotFoundError";
    this.resource = resource;
  }
}

function loadConfig(text) {
  try {
    return JSON.parse(text);
  } catch (error) {
    throw new Error("Could not read config", { cause: error });
  }
}

try {
  throw new NotFoundError("user 42");
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log("respond with 404:", error.message);
  } else {
    throw error; // not ours to handle
  }
}

try {
  loadConfig("{ broken");
} catch (error) {
  console.log(error.message, "caused by", error.cause.name); // ... SyntaxError
}
對本章有疑問嗎?
上一章Modules and Packages下一章Key Concepts: Async and Closures

Catching everything and carrying on silently hides bugs. Catch what you can actually handle and rethrow the rest.

Errors in async code

try...catch only sees a rejected Promise if you await it; without await, the rejection slips past. Node.js terminates the process on an unhandled rejection by default, so always handle them.

import { readFile } from "node:fs/promises";

async function readJson(path) {
  try {
    return JSON.parse(await readFile(path, "utf8"));
  } catch (error) {
    if (error.code === "ENOENT") return null; // missing file is fine
    throw error;
  }
}

// with a then chain, attach .catch
readJson("settings.json")
  .then((data) => console.log(data ?? "no settings"))
  .catch((error) => console.error("read failed:", error));

// see every outcome, success or failure
const results = await Promise.allSettled([readJson("a.json"), readJson("b.json")]);
for (const r of results) {
  console.log(r.status, r.status === "fulfilled" ? r.value : r.reason.message);
}

An error thrown inside a setTimeout callback also escapes a surrounding try...catch, because the callback runs later on its own. Chapter 6 explains why.

Testing with node:test

Node.js ships a test runner, node:test, and an assertion module, node:assert. Name files like *.test.js and node --test finds and runs them.

// age.test.js
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { parseAge } from "./age.js";

describe("parseAge", () => {
  it("converts numeric strings", () => {
    assert.equal(parseAge("29"), 29);
  });

  it("rejects negative numbers", () => {
    assert.throws(() => parseAge("-1"), RangeError);
  });

  it("handles async failures", async () => {
    await assert.rejects(Promise.reject(new Error("boom")), /boom/);
  });

  it("compares objects deeply", () => {
    assert.deepEqual({ a: [1, 2] }, { a: [1, 2] });
  });
});
node --test
node --test --watch

Other test runners

For richer features, the community favorites are Vitest, which is fast and pairs naturally with Vite, and Jest, which has years of documentation behind it. Both use a similar describe / it / expect style.

// sum.test.js (Vitest)
import { describe, it, expect } from "vitest";
import sum from "./math.js";

describe("sum", () => {
  it("adds every argument", () => {
    expect(sum(1, 2, 3)).toBe(6);
  });

  it("returns 0 with no arguments", () => {
    expect(sum()).toBe(0);
  });
});

Summary

  • Throw Error objects and catch them only where you can handle them.
  • Do cleanup in finally; preserve root causes with cause.
  • Handle async failures with await plus try...catch, or with .catch().
  • node:test and node:assert/strict cover a lot; reach for Vitest or Jest when you need more.

0 則留言

熱門留言由新到舊

登入 · 登入後即可留言。