Ctrl K
ComunidadGuías…

src/errors.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { WeaveError } from './store.js';

export const ERROR_CONTRACT = Object.freeze({
  invalid: { http: 400, mcp: -32602, exit: 40 },
  ambiguous: { http: 400, mcp: -32602, exit: 41 },
  slug_invalid: { http: 400, mcp: -32602, exit: 40 },
  slug_reserved: { http: 400, mcp: -32602, exit: 40 },
  forbidden: { http: 403, mcp: -32003, exit: 46 },
  'not-found': { http: 404, mcp: -32001, exit: 44 },
  conflict: { http: 409, mcp: -32002, exit: 45 },
  slug_taken: { http: 409, mcp: -32002, exit: 45 },
  stale: { http: 412, mcp: -32004, exit: 47 },
  'too-large': { http: 413, mcp: -32005, exit: 48 },
  'unsupported-type': { http: 415, mcp: -32006, exit: 49 },
  'rate-limited': { http: 429, mcp: -32007, exit: 50 },
  'weave-error': { http: 400, mcp: -32000, exit: 1 },
  'storage-full': { http: 507, mcp: -32008, exit: 51 },
  internal: { http: 500, mcp: -32603, exit: 70 },
});

export const storageFull = (err) => err?.code === 'ENOSPC' || err?.code === 'SQLITE_FULL' || err?.errcode === 13 || /database or disk is full/.test(String(err?.message ?? ''));

const codeOf = (err) => {
  if (err instanceof WeaveError) return Object.hasOwn(ERROR_CONTRACT, err.code) ? err.code : 'weave-error';
  return storageFull(err) ? 'storage-full' : 'internal';
};

export function contractFor(err) {
  const code = codeOf(err);
  return { code, ...ERROR_CONTRACT[code] };
}

export const statusFor = (err) => contractFor(err).http;

export function errorBody(err) {
  if (err instanceof WeaveError) return { error: err.message, code: err.code ?? 'weave-error' };
  const id = crypto.randomUUID().slice(0, 8);
  if (typeof console !== 'undefined') console.error(`weave: request ${id} failed:`, err);
  if (storageFull(err)) return { error: 'The weave server is out of storage, so nothing was saved. Ask whoever runs your weave to add storage.', code: 'storage-full', id };
  return { error: `Internal error (request ${id})`, code: 'internal', id };
}

export function mcpToolError(err) {
  const error = err?.message ?? String(err);
  const { code, mcp } = contractFor(err);
  const named = err instanceof WeaveError ? err.code ?? code : code;
  return { content: [{ type: 'text', text: `Error: ${error}` }], isError: true, structuredContent: { error, code: named, rpc: mcp } };
}

export function cliFailure(err) {
  const { code, exit } = contractFor(err);
  const named = err instanceof WeaveError ? err.code ?? code : code;
  return { line: `weave: error [${named}]: ${err?.message ?? String(err)}`, exit };
}

export function nonNegativeInteger(name, value, fallback = 0) {
  if (value == null) return fallback;
  const n = Number(value);
  if (!Number.isInteger(n) || n < 0) throw new WeaveError(`${name} must be a whole number of rows, not '${value}'`, 'invalid');
  return n;
}