Repository navigation
feat(platform): onRequestError, reporte de errores del navegador y runJob (0.7.0) - #16
Merged
Merged
Conversation
…nJob — 0.7.0 Aditivo: no cambia withApiHandler, getLogger ni configureTransport. dist/ regenerado y reproducible. Código escrito originalmente en el espejo ai4u-com-co/platform. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011UCi86Fu9p1HD1KNPsZXWG
…sibles en message y stack Añade redactSecrets(text) (pura, idempotente, regex lineales) y la aplica a message y stack de los errores del logger, y a String(err) cuando no es Error. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011UCi86Fu9p1HD1KNPsZXWG
…e entrada - JWT y prefijos de clave (AIza, ghp_, github_pat_, sb_*, sk-) usan lookbehind (?<![A-Za-z0-9_-]) en vez de \b para no reiniciar a mitad de una racha; los cuantificadores abiertos quedan acotados. - serializeErr recorta message a 16 384 y stack a 32 768 caracteres antes de redactar. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011UCi86Fu9p1HD1KNPsZXWG
…es de recortar - Se quitan las cotas superiores de los cuantificadores de JWT y claves: consumen toda la racha del token (el lookbehind y el tope de entrada mantienen el coste lineal). - serializeErr redacta una porción max+4096 y DESPUÉS recorta el resultado, para que una credencial a caballo del corte no filtre un fragmento. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011UCi86Fu9p1HD1KNPsZXWG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Por qué
La auditoría de cableado de errores (35 repos, 28-oct) mostró que
@ai4u/platformno tiene hoy: (1) un gancho para los errores del servidor que Next no pasa porwithApiHandler, (2) ningún reporte de errores del navegador (todos loserror.tsxsolo hacenconsole.error), ni (3) una forma estándar de registrar crons y trabajos en segundo plano (varios crons responden 200 aunque fallen, y variosafter()no hacen flush). Este PR añade las tres piezas, de forma aditiva: no cambiawithApiHandler,getLogger,configureTransportni el logger.Qué añade (v0.7.0, minor)
@ai4u/platform/instrumentation→onRequestError(err, request, context): firma verificada contra la documentación de Next 15/16; registra error,digest, ruta sin querystring, método y contexto del router; nunca lee headers ni cookies; haceflushLogs; no-op fuera del runtime Node; nunca lanza. Uso:export { onRequestError } from "@ai4u/platform/instrumentation".@ai4u/platform/client→installClientErrorReporteryreportClientError:addEventListener(no pisa handlers existentes), idempotente, dedupe de 60 s, tope de 5 por sesión, trunca mensaje y stack, solo viajalocation.pathname,sendBeaconcon fallback afetch keepalive. Ignora errores de carga de recursos,Script error.yResizeObserver loop.@ai4u/platform/client-errors→createClientErrorHandler: receptor paraapp/api/client-error/route.ts.@ai4u/platform/jobs→runJob(name, fn, { log?, rethrow?, tenant? }): registra inicio y fin con duración,log.errorsi lanza o si el resultado traeerrors/errores> 0, y siempreflushLogsenfinally.El navegador del visitante no tiene credenciales de servicio, así que
createClientErrorHandleres público. Mitigaciones incluidas: soloapplication/json, tope de tamaño (413), mismo origen (Sec-Fetch-Site/Origin, 403), límite por IP en memoria (429), validación estricta de forma, saneado y truncado de campos, claves sensibles descartadas, respuesta 204 sin eco. El cliente no puede fijar nivel, servicio nicomponentdel log. Límites conocidos (documentados en README y en el módulo): el límite por IP es de mejor esfuerzo en serverless (cada instancia tiene su Map), y las cabeceras de origen las puede falsificar un cliente que no sea navegador, así que no sustituye a un WAF. Los campos recibidos son datos no confiables.Para quien integre
/api/client-errordebe quedar pública o el reporte recibe 401 y se pierde.installClientErrorReporterva en un componente"use client"conuseEffect;error.tsx/global-error.tsxdeben llamarreportClientError.x-forwarded-host/host: si un proxy reescribe el host puede dar 403; probar en el primer repo que lo adopte.ERROR: vigilar el volumen la primera semana (el fixer nocturno los agrupará).Verificación
flushLogs()en elfinallyderunJobfallan 3 de 7 tests dejobs.kernel:npm ci,tsc --noEmitsin errores,npm test11 archivos / 116 tests verdes (31 nuevos),npm run buildcorrecto, y eldist/reconstruido es idéntico al commiteado (git diff packages/platform/distvacío).onRequestErrory la ruta de cliente dentro de una app Next real ni con el bundler Edge de Turbopack (la firma se verificó por documentación);sendBeacony el flujo de origen en navegadores reales (solo con stubs); nada en producción.ai4u-com-co/platform(donde se escribió por error primero): el espejo se sobrescribe en cada publicación, por eso este PR es la fuente de verdad.Paso humano para publicar
Tras revisar y mergear: tag
platform-v0.7.0(lo disparamirror.ymlhaciaai4u-com-co/platformcon tagv0.7.0). Los consumidores se actualizan con el bump bot. Hasta que exista el tag, ningún repo puede usar estas piezas.🔒 Endurecimiento del logger (commits 2 y 3)
Una revisión de seguridad de otro PR mostró que un
errcrudo puede llevar claves dentro del mensaje (p. ej. googleapis manda la clave de API como?key=…en la URL y los errores de red incluyen la URL). Se arregla en el origen, para todo el ecosistema:serializeErraplicaredactSecretsamessageystack: parámetros de query sensibles (key,token,access_token,signature…) →=[redacted];Bearer/Basic; JWT; formatos de clave conocidos (sk-,sk-ant-,sb_secret_,AIza…,ghp_,github_pat_); credenciales en URL. No redacta URLs enteras (se perdería diagnóstico).message16 384 caracteres,stack32 768 (con…[truncado]). Se redacta primero sobremax + 4096y se recorta DESPUÉS, para que una credencial a caballo del corte no sobreviva a trozos.eyJ…sin puntos (≈6 400–7 000 ms con"eyJaaaaa-".repeat(20000)). Ahora todos los patrones con prefijo usan(?<![A-Za-z0-9_-])(el motor no reinicia a mitad de una racha) y sin cotas superiores en los tokens, de modo que un token largo se enmascara entero: las cotas intermedias dejaban visible un JWT con un segmento > 4096 y la cola de una clave > 512 (hallazgos de la revisión). Con el anclaje y el tope de entrada el coste es lineal: 4,5 ms. Tests de rendimiento (< 200 ms) para 10 entradas patológicas.auth/code/session;sk-+8 caracteres puede dar un falso positivo; no limpia registros ya existentes enplatform_logs.Verificación final (kernel)
tscsin errores,npm test12 archivos / 133 tests, build reproducible (git diff packages/platform/distvacío tras segundo build).🤖 Generated with Claude Code
https://claude.ai/code/session_011UCi86Fu9p1HD1KNPsZXWG