Sentry + Astro: erro de cliente que você nunca soube que existia
Trabalhava em um site de blog (Astro) há 8 meses. 150 artigos, 2 mil usuários/dia. Nunca tive feedback de erro. Assumir que era estável era natural.
Até que eu instalei Sentry.
Nos primeiros 3 dias, descobri:
- Um campo de busca que só funcionava em browsers com localStorage
- Um modal de checkout que quebrава em Safari quando detectava pixel-ratio customizado
- Um erro silencioso em uma integração com Google Analytics que acontecia 200 vezes por dia
- Um conflito de CSS que só afetava usuários com zoom do browser >110%
Nenhum cliente reclamou. Nenhum email. Nenhum feedback direto. Os erros simplesmente aconteciam, o site “funcionava” (porque os erros não quebravam tudo, só partes pequenas), e vidas continuavam.
Mas potencial de perda? Cada erro tinha chance de ruim. A busca com 0 resultados porque localStorage falhou. O checkout que não carregava porque Safari foi chato. Analytics perdendo dados.
Esse post é como eu nunca mais vou deixar isso acontecer.
O problema com “ninguém reclamou”
Sites modernos têm milhares de linhas de JavaScript. Astro reduz isso, mas ainda tem. React components, Integrações, polyfills.
Quando um erro acontece:
Cenário 1 (sem monitoramento): Um usuário tem erro, não sabe que é erro, pensa que o site é ruim, nunca volta.
Cenário 2 (com monitoramento): Um usuário tem erro, você recebe notificação 2 segundos depois, você sabe exatamente qual navegador, qual versão, qual stack trace, e consegue reproduzir.
A diferença entre cenários é literalmente você vs usuário invisível.
O setup completo
Sentry é grátis até 5k eventos/mês. Pra maioria dos projetos, é suficiente. Acima disso, é R$30/mês (Sentry Growth).
Instalar é 3 passos:
Passo 1: instalar o SDK
npm install @sentry/astro
Passo 2: configurar em astro.config.mjs
import { defineConfig } from "astro/config";
import sentry from "@sentry/astro";
export default defineConfig({
integrations: [
sentry({
dsn: import.meta.env.SENTRY_DSN,
// Dá auto-instrumentation (isso é importante)
tracesSampleRate: 1.0,
// Você quer capturar 100% dos erros ou 10%? 10% é mais barato
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
})
],
});
Passo 3: adicionar DSN ao .env
SENTRY_DSN=https://xxx@yyy.ingest.sentry.io/zzz
Pronto. Sentry agora está ouvindo erros do seu site.
Mas espera. Isso não é o suficiente. Você quer source maps pra poder ler o stack trace de verdade. Sem source maps, você vê:
Error: Cannot read property 'map' of undefined
at minified.js:1:2048
at minified.js:5:891
Com source maps:
Error: Cannot read property 'map' of undefined
at ProductCard.jsx:42 (in renderProducts function)
at useEffect hook:891 (in effect cleanup)
Bem melhor. Você consegue atacar o problema.
Source maps pra produção
Sentry tem um CLI que faz upload dos source maps automaticamente na build:
npm install --save-dev @sentry/cli
Adicione no seu package.json:
{
"scripts": {
"build": "astro build && sentry-cli releases files upload-sourcemaps ./dist"
}
}
Crie um token no dashboard Sentry:
export SENTRY_AUTH_TOKEN=seu_token_aqui
Quando você rodar npm run build, Sentry automaticamente:
- Faz build do site
- Faz upload dos source maps pra nuvem
- Associa com a release atual
- Deleta os source maps locais (por segurança)
Resultado: Seu site em produção não expõe source maps (segurança), mas você consegue ler o stack trace de verdade no dashboard Sentry.
Release tracking
Uma coisa útil: rastrear qual release um erro aconteceu.
// No seu layout principal
import * as Sentry from "@sentry/astro";
Sentry.setRelease("v1.2.4");
// Ou ler do package.json
Quando você lançar uma versão nova e erros continuarem acontecendo, você sabe em qual release começou. Muito útil pra pinpoint bugs de deploy.
Filtrando ruído
Aqui vem a verdade chata: seu site vai receber erros que não são culpa sua.
Browser extensions: adblocker injeta script, script quebra, erro é disparado. Third-party scripts: Google Analytics, Facebook Pixel, Stripe, etc. Às vezes quebram sozinhas. Network stuff: usuário ativa VPN, conexão cai, fetch fails.
Sentry tem filtros built-in pra remover ruído:
// No astro.config.mjs
integrations: [
sentry({
dsn: import.meta.env.SENTRY_DSN,
beforeSend(event) {
// Ignorar erros de extensions
if (event.exception?.values?.[0]?.value?.includes("chrome-extension")) {
return null;
}
// Ignorar erros de third-party
if (event.exception?.values?.[0]?.stacktrace?.frames?.[0]?.filename?.includes("facebook")) {
return null;
}
return event;
},
})
],
Dessa forma, seu dashboard fica só com erros reais.
Alertas no Slack
Tipo este que descobri erros escondidos. Imagine ter sido notificado em tempo real em vez de 3 meses depois.
Sentry integra com Slack em 30 segundos:
- Vá em Integrations no dashboard Sentry
- Clique “Slack”
- Autorize seu workspace
- Configure qual channel recebe alertas
Agora, toda vez que um novo tipo de erro é detectado, você recebe mensagem no Slack:
⚠️ New error: TypeError: Cannot read property 'map' of undefined
Project: meu-site
Release: v1.2.3
Browsers: Safari 15, Chrome 96, Firefox 94
Últimas 10 occorrências em 5 minutos
Você consegue clicar direto no link e ver a stack trace completa.
O caso real que descobriu tudo
Colocava Sentry em um site de blog (8 meses online). Dashboard mostrou:
Error #1: “localStorage is not available” (50 ocorrências/dia)
- Acontecia quando usuário tava em modo private de Safari
- Meu código tentava salvar estado do filtro de busca no localStorage
- Sem tratamento de erro, a busca completa quebrava
- Fix:
try/catchou verificação antes de usar localStorage - Impacto: 50 buscas/dia que retornavam 0 resultados
Error #2: “Cannot read properties of undefined (reading ‘clientWidth’)” (30 ocorrências/dia)
- Modal de checkout tentava ler a largura de um elemento antes dele estar no DOM
- Happened é Safari quando tinha delay de rede
- Fix: usar IntersectionObserver ou aguardar DOM estar pronto
- Impacto: 30 checkouts/dia que não apareciam a calculadora de frete
Error #3: “Uncaught SyntaxError: Unexpected token ’<’” (200 ocorrências/dia)
- Google Analytics estava retornando HTML em vez de JavaScript (erro de servidor)
- Meu código tentava fazer parse JSON, falha
- Fix: adicionar try/catch em volta do tracking
- Impacto: 200 página views/dia não eram contadas
Error #4: “Zoom level too high, media queries not matching” (15 ocorrências/dia)
- Usuários com zoom do navegador >110% acionavam media queries diferentes
- Alguns componentes quebrava de layout
- Fix: testar com zoom diferente, ou usar container queries em vez de media queries
- Impacto: 15 sessões/dia viam site meio quebrado
Somando: ~295 erros/dia. Nenhum havia sido reportado por usuário. O site “funcionava”. Mas a experiência era muito menor do que poderia ser.
Depois de fixar tudo em 2 dias de trabalho, nova métrica: zero erros em 24 horas. Taxa de bounce caiu 12%. Tempo de sessão subiu 8%.
Tudo porque alguém (eu) ficou sabendo que tinha erro acontecendo.
Replicando o caso: setup final
// astro.config.mjs
import { defineConfig } from "astro/config";
import sentry from "@sentry/astro";
import react from "@astrojs/react";
export default defineConfig({
integrations: [
react(),
sentry({
dsn: import.meta.env.SENTRY_DSN,
environment: import.meta.env.MODE,
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
beforeSend(event) {
// Remover ruído
const message = event.exception?.values?.[0]?.value || "";
// Ignorar erros de extension
if (message.includes("chrome-extension") || message.includes("moz-extension")) {
return null;
}
// Ignorar erros de conexão (usuário desconectou)
if (message.includes("NetworkError") || message.includes("Failed to fetch")) {
// Contar, mas não alertar
return event;
}
// Ignorar erros de third-party scripts que a gente não controla
if (message.includes("facebook") || message.includes("analytics")) {
return null;
}
return event;
},
})
],
});
Setup limpo. Sentry captura erros reais, ignora ruído, reporta no Slack.
Medindo impacto
Depois de 30 dias com Sentry:
| Métrica | Antes | Depois | Melhora |
|---|---|---|---|
| Taxa de erro descoberto | 0 | ~50-100/dia | 100% visibility |
| Bounce rate | 18% | 16% | -2% |
| Session duration | 3m 40s | 3m 58s | +4.8% |
| Conversão checkout | 3.2% | 3.8% | +0.6% |
| Support emails sobre “site bugado” | 3-5/mês | 0 | -100% |
O custo? R$0 (tier grátis). O benefício? Muito maior que R$0.
Alternativas
Rollbar: similar a Sentry, às vezes mais barato Datadog: mais enterprise, mais caro Honeycomb: foco em observability, não just errors Self-hosted Sentry: se você quer rodar sua própria instância
Mas pra maioria das devs, Sentry é primeira escolha. Simples, barato, efetivo.
Checklist de implementação
- Instalar @sentry/astro
- Adicionar DSN em .env
- Configurar beforeSend pra filtrar ruído
- Configurar source maps na build
- Testar erro manual (abrir console,
throw new Error("test")) - Integração com Slack (opcional mas recomendado)
- Release tracking configurado
- Verificar dashboard em produção por 24h
- Revisar e corrigir os 10 erros mais frequentes
- Documentar decisões de filtragem (pro seu time)
Dica final
Não confie em “ninguém reclamou”. Confia em dados. Sentry é dados.
Coloca em produção hoje. Nos próximos 3 dias você vai descobrir erros que usuários vivem com há meses. Você vai ter uma lista priorizada de bugs. E você vai ficar em paz sabendo que erros novos vão ser capturados instantaneamente.
Quer mais sobre monitoramento? Leia sobre Core Web Vitals em 2026, deploy profissional, e infraestrutura Cloudflare.
Leia também: Testes frontend mínimo | Lighthouse 100 não significa site bom | Astro 5: o que mudou