SDK
Referência do bridge: init, captura de erros, contexto, React, TanStack Query e source maps.
O SDK tem dois pacotes. O @mira/bridge fica na app e cuida do widget, da captura de erros e do contexto. O @mira/sourcemaps roda no build e envia os source maps. Para instalar e configurar cada um, siga Integrar uma app.
npm install https://mira.example.com/downloads/sdk/mira-bridge-0.15.0.tgz
npm install --save-dev https://mira.example.com/downloads/sdk/mira-sourcemaps-0.1.1.tgzO bridge exporta:
| Import | Conteúdo |
|---|---|
@mira/bridge | mira, com init, open, setContext, register, setUser, captureException, captureMessage, lastEventId, addErrorExtractor e sessionEventIds |
@mira/bridge/widget | widgetIntegration, para ativar o widget junto com a captura de erros |
@mira/bridge/react | ErrorBoundary |
@mira/bridge/tanstack-query | tanstackQueryIntegration |
Iniciar
import { mira } from "@mira/bridge";
mira.init({
dsn: import.meta.env.VITE_MIRA_DSN,
release: `${version}+${import.meta.env.VITE_BUILD_SHA}`,
buildTime: import.meta.env.VITE_BUILD_TIME,
sampleRate: 1,
});| Opção | Uso |
|---|---|
dsn | Ativa a captura de erros. Vazio ou ausente, o SDK de erros fica desativado. Malformado, o SDK avisa no console com o prefixo [Mira] e fica desativado, sem lançar erro |
release | Versão e SHA curto, como 1.4.0+abc1234. Entra em filtros e na detecção de regressão |
buildTime | Horário do build (ISO, número ou Date). Sem ele, o Mira não reabre um erro resolvido |
sampleRate | Fração das ocorrências enviadas, de 0 a 1. Padrão 1 |
beforeSend(event, { originalException }) | Altera a ocorrência ou descarta com null. A redação roda depois |
integrations | Lista de integrações, como a do TanStack Query e a do widget |
redaction.extraKeyPatterns | Nomes de chave extras para redigir, somados aos padrões |
dedupeWindowMs | Janela do dedupe. Padrão 5 s |
maxEventsPerPage | Envios por carregamento de página. Padrão 100 |
environment | Informativo: o ambiente vem da chave do DSN. Se divergir, o SDK avisa uma vez no console |
mira.init({ integrations: [widgetIntegration({ instanceUrl })] }) ativa só o widget. Passe também dsn para ativar a captura de erros. O atalho mira.init({ instanceUrl }) foi removido: sem a integração, o SDK avisa no console e o widget não abre.
Opções do widget
| Opção | Uso |
|---|---|
instanceUrl | URL do Mira, como https://mira.example.com. Obrigatória |
trigger | "button" (padrão), "shortcut" ou "manual" |
shortcut | Combinação do atalho, como "Ctrl+Shift+M". O padrão é Alt+Shift+M |
capture | false impede o widget de iniciar a captura de console, erros e rede. Screenshots, arquivos e texto continuam disponíveis |
Com trigger: "manual", nenhum botão aparece. Chame mira.open() a partir de um menu da app.
O que vira ocorrência
| Fonte | level | Tag mechanism |
|---|---|---|
window.onerror | error | onerror |
unhandledrejection | error | unhandledrejection |
console.error | error | console |
console.warn | warning | console |
ErrorBoundary | error | react |
Query ou mutation do TanStack Query que falhou depois do retry | error | tanstack-query ou tanstack-mutation |
Um console.error ou console.warn com um Error nos argumentos vira exceção. Sem Error, vira mensagem com os argumentos em texto. O mesmo objeto de erro conta uma vez só, mesmo que chegue por mais de um caminho.
Capturar à mão
const eventId = mira.captureException(error, {
request: { url, method, headers, body },
response: { status, body },
tags: { feature: "checkout" },
});
mira.captureMessage("Pagamento recusado sem motivo", "warning");
mira.lastEventId();request e response aceitam Request e Response nativos ou objetos simples. De um Response nativo o SDK lê só status e URL, porque o corpo já foi consumido. Para enviar o corpo, passe o objeto simples. No nível de dados mínimo do ambiente, os corpos não saem do navegador.
captureException devolve o id da ocorrência, ou undefined quando a amostragem, o beforeSend ou o limite maxEventsPerPage a descarta. Use mira.lastEventId() na página de erro da app para mostrar o id à pessoa, que pode colar o id na busca de Erros.
Validação de resposta com Zod
Quando o parse com Zod roda depois do client HTTP, capture o ZodError junto com o request:
const response = await apiClient.get(url);
const parsed = schema.safeParse(response.data);
if (!parsed.success) {
mira.captureException(parsed.error, {
request: { url, method: "GET" },
response: { status: response.status, body: response.data },
});
}O extrator embutido envia cada issue com caminho, código, esperado, recebido e mensagem. A mensagem sai das issues sem o valor recebido, então o agrupamento não muda com o valor e uma senha não vaza pela mensagem. No nível de dados completo, o detalhe mostra o valor recebido, lido do corpo da resposta pelo path de cada issue.
Extratores da app
mira.addErrorExtractor((error) =>
error instanceof ApiError
? {
tags: { api: error.service },
fingerprint: [error.code],
details: [{ kind: "custom", name: "api", data: { code: error.code, traceId: error.traceId } }],
}
: undefined,
);O extrator devolve type, value, fingerprint, tags e details, ou undefined para erros que não conhece. Os extratores rodam na ordem de registro, depois do de Zod: type, value e fingerprint do último valem, as tags se juntam e os details se somam. Coloque em details o que varia a cada ocorrência, porque details não entra no agrupamento. Um detalhe custom aceita até 50 chaves com valores primitivos. Um extrator que lança erro é ignorado.
Cadeia de cause
Cada nível de error.cause entra na exceção, do mais próximo ao mais distante, com tipo, mensagem e stack, até cinco níveis.
Usuário e contexto
mira.setUser({ id: user.id, email: user.email });
mira.setUser(null); // no logoutSem setUser, o SDK usa um id anônimo aleatório, salvo no localStorage, para contar usuários afetados. No nível de dados mínimo, o Mira descarta o email.
mira.setContext({ version, env, appUser }) define o contexto que vai nos reports, e mira.register(nome, provider) registra um snapshot de estado. Os dois estão em Integrar uma app.
React e TanStack Query
O núcleo não importa React. O ErrorBoundary e a integração com o TanStack Query ficam em subpaths:
import { ErrorBoundary } from "@mira/bridge/react";
import { tanstackQueryIntegration } from "@mira/bridge/tanstack-query";
mira.init({ dsn, integrations: [tanstackQueryIntegration(queryClient)] });
<ErrorBoundary
fallback={({ eventId, resetError }) => <ErrorPage eventId={eventId} onRetry={resetError} />}
>
<App />
</ErrorBoundary>;A integração escuta o QueryCache e o MutationCache do QueryClient e envia as tags query.key ou mutation.key, só com o primeiro segmento da key. O resto da key costuma trazer filtros e ids digitados e fica fora do evento.
Widget como integração
Em desenvolvimento, QA e staging, o widget entra como integração da captura de erros:
import { widgetIntegration } from "@mira/bridge/widget";
mira.init({ dsn, integrations: [widgetIntegration({ instanceUrl: "https://mira.example.com", trigger: "button" })] });Sem o widget, o build de produção não baixa a interface dele: o núcleo só carrega o widget por import().
Breadcrumbs
Cada ocorrência leva até 100 breadcrumbs, do mais antigo ao mais recente:
console: as chamadas de console, com o texto dos argumentos.fetchexhr: método, URL e status, sem headers nem corpos.navigation: trocas de URL porpushState,replaceState,popstateehashchange.
As requisições do próprio SDK ao Mira ficam fora.
Redação
A redação roda na página antes do envio, depois do beforeSend, e o Mira a aplica de novo antes de gravar. Ela cobre os headers Authorization, Cookie e Set-Cookie, chaves sensíveis (como token, password e secret), JWTs, tokens Bearer e pares chave=valor. Remove senhas embutidas em URLs. Nas URLs, também esconde os parâmetros code, state, id_token, access_token e refresh_token, como os de um callback OAuth.
A redação não reconhece dados pessoais soltos, como um nome ou email em ?q=. Evite dados pessoais na query string ou cadastre o nome da chave em redaction.extraKeyPatterns.
Dedupe e limites
A mesma ocorrência sai na primeira vez. As repetições dentro de dedupeWindowMs saem juntas no fim da janela, como uma ocorrência com contador. Depois de maxEventsPerPage envios, o SDK descarta o resto até a página recarregar, para conter loops de erro.
Um evento cabe em 200 KiB. Acima disso, o SDK corta, nesta ordem: corpos do request, breadcrumbs mais antigos, causas, detalhes, estado e, por fim, a mensagem. Quando a ingestão responde 429, o SDK pausa os envios pelo tempo do cabeçalho Retry-After.
Source maps
Plugin Vite
import { miraSourceMaps } from "@mira/sourcemaps/vite";
miraSourceMaps({ release, buildTime });| Opção | Padrão |
|---|---|
release | Obrigatória. A mesma do mira.init |
buildTime | Início do build. Use o mesmo valor do mira.init |
url | Variável MIRA_URL |
projectId | Variável MIRA_PROJECT_ID |
token | Variável MIRA_SOURCEMAPS_TOKEN |
O plugin só roda em vite build. Sem token, os maps são removidos sem envio e o log avisa. Com token e sem URL ou ID do projeto, o build falha.
Linha de comando
mira-sourcemaps upload dist --release 1.4.0+abc1234 [--build-time <iso>] [--url <url>] [--project <id>]
mira-sourcemaps check distupload injeta os Debug IDs, envia os maps e apaga os .map do diretório. check sai com erro se sobrar um .map. Os dois leem a credencial de MIRA_SOURCEMAPS_TOKEN.