{"id":"1368d1bb49bc8103","repo":"vitest-dev/vitest","slug":"error-message","errorCode":null,"errorMessage":"${error.message}","messagePattern":"\\$\\{error\\.message\\}","errorType":"exception","errorClass":"PrettyFormatPluginError","httpStatus":null,"severity":"error","filePath":"packages/pretty-format/src/index.ts","lineNumber":355,"sourceCode":"          val,\n          valChild => printer(valChild, config, indentation, depth, refs),\n          (str) => {\n            const indentationNext = indentation + config.indent\n            return (\n              indentationNext\n              + str.replaceAll(NEWLINE_REGEXP, `\\n${indentationNext}`)\n            )\n          },\n          {\n            edgeSpacing: config.spacingOuter,\n            min: config.min,\n            spacing: config.spacingInner,\n          },\n          config.colors,\n        )\n  }\n  catch (error: any) {\n    throw new PrettyFormatPluginError(error.message, error.stack)\n  }\n  if (typeof printed !== 'string') {\n    throw new TypeError(\n      `pretty-format: Plugin must return type \"string\" but instead returned \"${typeof printed}\".`,\n    )\n  }\n  return printed\n}\n\nfunction findPlugin(plugins: Plugins, val: unknown) {\n  for (const plugin of plugins) {\n    try {\n      if (plugin.test(val)) {\n        return plugin\n      }\n    }\n    catch (error: any) {\n      throw new PrettyFormatPluginError(error.message, error.stack)","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/pretty-format/src/index.ts#L337-L373","documentation":"While serializing a value, pretty-format invokes the matching plugin's `serialize` (new-style) or `print` (old-style). If that call throws, the error is wrapped in a `PrettyFormatPluginError` carrying the original message and stack so the culprit plugin is identifiable. The text shown is the original error's `.message`.","triggerScenarios":"A plugin's serialize accesses a property whose getter throws; a built-in plugin (React/DOM/Immutable) chokes on an exotic object; a custom plugin has a runtime bug triggered by the specific value.","commonSituations":"Snapshotting objects with throwing getters; serializing Proxy objects; third-party pretty-format plugins; React/DOM element plugin hitting non-standard instances.","solutions":["Read the `PrettyFormatPluginError.stack` to identify which plugin threw.","Make the offending object's getter non-throwing, or avoid snapshotting it directly.","Disable the culprit plugin by passing a filtered `plugins` array to `format()`.","Wrap your own plugin's serialize in try/catch and return a fallback string."],"exampleFix":"// before: custom plugin throws on null\nconst plugin = {\n  test: v => v?.custom,\n  serialize: v => v.custom.toString(), // throws if v.custom is null\n}\n\n// after\ncustom:\nconst plugin = {\n  test: v => v?.custom != null,\n  serialize: v => String(v.custom),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  format(value, { plugins: [myCustomPlugin, ...plugins] })\n}\ncatch (err) {\n  if (err instanceof Error && err.name === 'PrettyFormatPluginError') {\n    console.error('Plugin failed:', err.message, '\\n', err.stack)\n    // fall back to a minimal safe serialization\n    return safeStringify(value)\n  }\n  throw err\n}","preventionTips":["Keep custom plugins' serialize defensive (try/catch around risky property access).","Filter the `plugins` array to only those you trust for a given value type.","Avoid snapshotting objects with throwing getters or hostile Proxies."],"tags":["pretty-format","plugins","snapshot","serialization"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}