web-print-pdf 前端的错误处理可参考这个标准处理

三层错误:分清来源即可,不必拆多个 catch

层级 何时触发 识别要点
传输层 客户端未启动、端口不通、WS 断开 try/catch + onError;打印前 getConnectStatus()
业务层 客户端已连接,但打印/渲染失败 响应 success: false → Promise reject,读 message
应用层 参数不合法、未 await、打印机名写死 封装校验 + 友好提示;见下文排障表

标准响应与失败形态

每条 WebSocket 回包均带 idtypetimestampsuccess。npm 包按 id 匹配请求:success: true 时 resolve,falsereject 整条 message 对象(不是 Error 实例)。

失败示例:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": 1710000001000,
  "type": "printHtml",
  "success": false,
  "message": "printing exited with exit code: 1",
  "data": null
}

成功示例:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": 1710000001000,
  "type": "printHtml",
  "success": true,
  "data": { "pdfPath": "...", "pdfUrl": "...", "pdfFileName": "..." },
  "extraOptions": { "action": "print" }
}

统一报错(复制即用)

SDK 失败时 reject 的可能是整条 message 对象(非 Error),直接 alert(err) 往往无效。复制下面这一个函数到项目(如 src/utils/print-error.js),在 catch 里统一转成可读文案即可。

/** 把 reject / 异常转成可展示的字符串 */
export function formatPrintError(err, fallback = '未知错误') {
  if (!err) return fallback;
  if (typeof err === 'string') return err;
  if (err instanceof Error && err.message) return err.message;
  if (typeof err === 'object' && err !== null) {
    if (typeof err.message === 'string' && err.message) return err.message;
    if (typeof err.msg === 'string' && err.msg) return err.msg;
  }
  try { return JSON.stringify(err); } catch { return String(err); }
}

业务侧写法(与在线样例一致):

import webPrintPdf from 'web-print-pdf';
import { formatPrintError } from './print-error.js';

async function onPrintClick() {
  try {
    const status = await webPrintPdf.utils.getConnectStatus();
    if (status.success !== true) throw status;

    const result = await webPrintPdf.printHtml(
      document.getElementById('area').innerHTML,
      { paperFormat: 'A4', printBackground: true },
      { paperFormat: 'A4' },
      { action: 'print', requestTimeout: 15 }
    );
    console.log('打印成功', result);
  } catch (err) {
    alert(formatPrintError(err)); // 或 toast / ElMessage
  }
}

printHtmlByUrlbatchPrintgetPrinterList 等 API 同样包在 try/catch 里,失败时都用 formatPrintError(err) 提示用户。预检不需要另写一套——示例里打印前的 getConnectStatus 未通过时 throw status,与打印失败进同一个 catch 即可。

getConnectStatussuccess === true 判断就绪(实测 data 常为布尔 true,不是 { connected: true })。连接失败、预检失败、打印失败 reject 的对象都走 formatPrintError

onResponse 与 onError 回调

除 Promise 外,可注册全局回调做日志、埋点或 UI 提示:

// 所有回包(成功 + 失败)都会触发
webPrintPdf.utils.onResponse((msg) => {
  console.log('[print-ws]', msg.type, msg.success, msg.message || '');
});

// 仅 WebSocket 传输错误(如连接异常)
webPrintPdf.utils.onError((e) => {
  console.error('[print-ws-error]', e);
});
API作用范围适用场景
try/catch单次调用按钮点击、表单提交——给用户即时反馈
onResponse全局每条回包审计日志、联调、统计成功率
onErrorWS 传输层监控断线、提示「请重启客户端」
业务失败(success:false)走 Promise reject 和 onResponse,不一定触发 onError。勿只用 onError 判断打印是否成功。

常见错误场景与处理

现象 / message 可能原因 处理建议
WebSocket connection failed / 连接被拒绝 客户端未运行或端口被占用 启动客户端;核对界面端口;避免多实例抢端口
websocket has not been connected 未 await、在连接完成前连续发请求 API 必须 await;避免同步链式无等待调用
printing exited with exit code: 1 等出纸失败 action 为 print 时 printerName 无效;preview 可能回退默认打印机而不报错 getPrinterList() 选 name;联调打印机用 action: 'print' 测,别只用 preview 判断
preview 成功但打到了错误打印机 非法 printerName 在 preview 下可能被忽略 正式出纸前用 print 验证打印机;或省略 printerName 明确使用默认机
URL 加载超时 / timeout 内网页面慢、requestTimeout 过短 增大 extraOptions.requestTimeout;检查 cookies/headers
参数校验失败 / 水印无效 pdfOptions 字段不合法 打印参数详解:watermark.color 用 rgb、angle≥0 等
batchPrint 部分任务失败 单条任务参数或内容异常 查看客户端「日志」页;拆分批次定位问题任务

Vue 3 封装示例

import { ref } from 'vue';
import webPrintPdf from 'web-print-pdf';
import { formatPrintError } from './print-error.js';

export function usePrintWithError() {
  const loading = ref(false);
  const lastError = ref('');

  async function printHtml(html, pdfOptions, printOptions, extraOptions) {
    loading.value = true;
    lastError.value = '';
    try {
      const status = await webPrintPdf.utils.getConnectStatus();
      if (status.success !== true) throw status;
      return await webPrintPdf.printHtml(html, pdfOptions, printOptions, extraOptions);
    } catch (err) {
      lastError.value = formatPrintError(err);
      return null;
    } finally {
      loading.value = false;
    }
  }

  return { loading, lastError, printHtml };
}

模板里用 lastError 绑定提示组件,loading 禁用按钮即可。

生产环境排障清单

  1. 浏览器控制台是否有 WS 连到 ws://127.0.0.1:端口/websocket/standard
  2. 客户端「日志」页是否有对应 id 的失败记录
  3. action: 'preview' 先验证 PDF 生成,再排查 printOptions
  4. 换一台机器复现,排除打印机驱动问题
  5. 在线样例跑「连接状态」与失败 demo,对比环境差异
免费下载客户端 打开在线样例