hobots 1.9.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/index.cjs +34 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -43
- package/dist/index.d.ts +31 -43
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/docs/api-reference.md +14 -20
- package/docs/concepts.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/tasks.md +19 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -264,7 +264,6 @@ interface RunContext {
|
|
|
264
264
|
signal: AbortSignal;
|
|
265
265
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
266
266
|
sleep(ms: number): Promise<void>; // espera cancelável — rejeita com RunCanceled no abort
|
|
267
|
-
attach(image, options?): Promise<AttachResult>; // anexa um print a uma linha de log
|
|
268
267
|
}
|
|
269
268
|
```
|
|
270
269
|
|
|
@@ -274,7 +273,6 @@ interface RunContext {
|
|
|
274
273
|
- **`ctx.signal`** — `AbortSignal` que dispara quando a run é **cancelada no app**, em **timeout** ou no **shutdown**.
|
|
275
274
|
- **`ctx.throwIfCanceled()`** — o ponto de parada de uma linha; lança `RunCanceled` se o `signal` já disparou.
|
|
276
275
|
- **`ctx.sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim).
|
|
277
|
-
- **`ctx.attach(image, options?)`** — anexa um print da tela à linha de log (veja [Anexos](#anexos-screenshots) abaixo).
|
|
278
276
|
- **Retorno** — **ignorado**: o SDK não captura nem envia o valor retornado pelo handler (resultados podem conter dados sensíveis e não são coletados).
|
|
279
277
|
- **Erro lançado** — a run é reportada como `failed` (mensagem cap 10k, stack 20k).
|
|
280
278
|
|
|
@@ -282,23 +280,27 @@ interface RunContext {
|
|
|
282
280
|
|
|
283
281
|
### Anexos (screenshots)
|
|
284
282
|
|
|
285
|
-
Texto de log conta o que o robô fez; um print conta **como estava a tela**. `
|
|
283
|
+
Texto de log conta o que o robô fez; um print conta **como estava a tela**. Os métodos de captura (`Hobots.captureException` e `Hobots.captureMessage`) aceitam um `attachment` no hint: dentro de uma execução de task, a imagem vira anexo da linha de log da run que espelha a captura — no app ela aparece como miniatura logo abaixo dessa linha, clicável para ampliar.
|
|
286
284
|
|
|
287
285
|
```js
|
|
288
286
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
289
287
|
await entrar();
|
|
290
|
-
|
|
288
|
+
Hobots.captureMessage('portal após o login', 'info', {
|
|
289
|
+
attachment: await page.screenshot(),
|
|
290
|
+
});
|
|
291
291
|
|
|
292
292
|
try {
|
|
293
293
|
await emitir(params);
|
|
294
294
|
} catch (erro) {
|
|
295
|
-
|
|
295
|
+
Hobots.captureException(erro, {
|
|
296
|
+
attachment: { image: await page.screenshot(), caption: 'tela no momento do erro' },
|
|
297
|
+
});
|
|
296
298
|
throw erro;
|
|
297
299
|
}
|
|
298
300
|
});
|
|
299
301
|
```
|
|
300
302
|
|
|
301
|
-
**O SDK não tira o print** — ele recebe a imagem pronta, de onde você quiser (Playwright, Puppeteer, uma lib de captura de desktop, um arquivo em disco).
|
|
303
|
+
**O SDK não tira o print** — ele recebe a imagem pronta, de onde você quiser (Playwright, Puppeteer, uma lib de captura de desktop, um arquivo em disco). O `attachment` aceita bytes (`Uint8Array`/`ArrayBuffer`/`Buffer`), um caminho de arquivo (só em Node) ou um objeto `{ image, caption?, contentType? }`.
|
|
302
304
|
|
|
303
305
|
| Limite | Valor |
|
|
304
306
|
| --- | --- |
|
|
@@ -307,7 +309,7 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
307
309
|
| anexos por execução | 20 |
|
|
308
310
|
| anexos por linha de log | 4 |
|
|
309
311
|
|
|
310
|
-
A linha de log é registrada **na hora**; o upload roda em segundo plano e vai direto para o S3 por URL presignada, sem passar pela API
|
|
312
|
+
A linha de log é registrada **na hora**; o upload roda em segundo plano e vai direto para o S3 por URL presignada, sem passar pela API — a captura **nunca bloqueia nem lança** por causa do anexo (falhas viram um aviso no log da run). Fora de uma execução de task não há onde pendurar a imagem: o `attachment` é descartado com um aviso. Detalhes em [Anexos](./docs/tasks.md#anexos-screenshots).
|
|
311
313
|
|
|
312
314
|
> **Dados sensíveis:** o print é enviado **exatamente como está** — o SDK não borra nem recorta nada, e telas de portal costumam conter CPF, nome e valores. Capture só o necessário. Solicitantes só veem os anexos quando o projeto está com "mostrar logs para solicitantes" ligado, o mesmo gate dos logs.
|
|
313
315
|
|
package/dist/index.cjs
CHANGED
|
@@ -1172,8 +1172,7 @@ var RunReporter = class {
|
|
|
1172
1172
|
throwIfCanceled: () => {
|
|
1173
1173
|
if (signal.aborted) throw runCanceledError();
|
|
1174
1174
|
},
|
|
1175
|
-
sleep: (ms) => cancelableSleep(ms, signal)
|
|
1176
|
-
attach: (image, options) => this.attach(image, options)
|
|
1175
|
+
sleep: (ms) => cancelableSleep(ms, signal)
|
|
1177
1176
|
};
|
|
1178
1177
|
}
|
|
1179
1178
|
context;
|
|
@@ -1318,7 +1317,8 @@ var RunReporter = class {
|
|
|
1318
1317
|
/**
|
|
1319
1318
|
* Registra a linha de log com o id do anexo (síncrono, na ordem certa) e dispara
|
|
1320
1319
|
* o upload em segundo plano. Nunca lança: todo caminho de erro vira `{ ok: false }`
|
|
1321
|
-
* com um aviso no log da run.
|
|
1320
|
+
* com um aviso no log da run. Chega ao handler pelos capture* do SDK — o hint
|
|
1321
|
+
* `attachment` de Hobots.captureException/captureMessage cai aqui via run-context-store.
|
|
1322
1322
|
*/
|
|
1323
1323
|
async attach(image, options = {}) {
|
|
1324
1324
|
const id = uuid4();
|
|
@@ -1505,6 +1505,9 @@ async function runWithRunContext(store, fn) {
|
|
|
1505
1505
|
function currentRunTransaction() {
|
|
1506
1506
|
return storage?.getStore()?.tx;
|
|
1507
1507
|
}
|
|
1508
|
+
function currentRunAttach() {
|
|
1509
|
+
return storage?.getStore()?.attach;
|
|
1510
|
+
}
|
|
1508
1511
|
|
|
1509
1512
|
// src/tasks/shutdown.ts
|
|
1510
1513
|
var WATCHED_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
@@ -1746,7 +1749,10 @@ var TaskAgent = class {
|
|
|
1746
1749
|
}
|
|
1747
1750
|
this.logger.debug(`executando run ${run.id} (${run.task})`);
|
|
1748
1751
|
try {
|
|
1749
|
-
await runWithRunContext(
|
|
1752
|
+
await runWithRunContext(
|
|
1753
|
+
{ runId: run.id, tx, attach: (image, options) => reporter.attach(image, options) },
|
|
1754
|
+
() => this.invokeWithTimeout(handler, run, reporter)
|
|
1755
|
+
);
|
|
1750
1756
|
await reporter.finalizeAttachments();
|
|
1751
1757
|
tx.setStatus("ok");
|
|
1752
1758
|
tx.finish();
|
|
@@ -1836,10 +1842,34 @@ function init(options) {
|
|
|
1836
1842
|
function getClient() {
|
|
1837
1843
|
return client;
|
|
1838
1844
|
}
|
|
1845
|
+
function toRunLogLevel(level) {
|
|
1846
|
+
return level === "fatal" ? "error" : level;
|
|
1847
|
+
}
|
|
1848
|
+
function forwardAttachment(attachment, message, level) {
|
|
1849
|
+
const attach = currentRunAttach();
|
|
1850
|
+
if (!attach) {
|
|
1851
|
+
client?.logger.warn("attachment descartado \u2014 s\xF3 \xE9 suportado dentro de uma execu\xE7\xE3o de task (register/start)");
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
const withMeta = typeof attachment === "object" && "image" in attachment ? attachment : { image: attachment };
|
|
1855
|
+
void attach(withMeta.image, {
|
|
1856
|
+
message,
|
|
1857
|
+
level: toRunLogLevel(level),
|
|
1858
|
+
caption: withMeta.caption,
|
|
1859
|
+
contentType: withMeta.contentType
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1839
1862
|
function captureException(error, hint) {
|
|
1863
|
+
if (hint?.attachment) {
|
|
1864
|
+
const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
1865
|
+
forwardAttachment(hint.attachment, message, hint.level ?? "error");
|
|
1866
|
+
}
|
|
1840
1867
|
return client?.captureException(error, hint, scope);
|
|
1841
1868
|
}
|
|
1842
1869
|
function captureMessage(message, level = "info", hint) {
|
|
1870
|
+
if (hint?.attachment) {
|
|
1871
|
+
forwardAttachment(hint.attachment, message, hint.level ?? level);
|
|
1872
|
+
}
|
|
1843
1873
|
return client?.captureMessage(message, level, hint, scope);
|
|
1844
1874
|
}
|
|
1845
1875
|
function addBreadcrumb(crumb) {
|