Voltar ao blog
Tutorial

Sentry + Astro: erro de cliente que você nunca soube que existia

Por Flávio Emanuel · · 10 min de leitura

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:

  1. Um campo de busca que só funcionava em browsers com localStorage
  2. Um modal de checkout que quebrава em Safari quando detectava pixel-ratio customizado
  3. Um erro silencioso em uma integração com Google Analytics que acontecia 200 vezes por dia
  4. 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:

  1. Faz build do site
  2. Faz upload dos source maps pra nuvem
  3. Associa com a release atual
  4. 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:

  1. Vá em Integrations no dashboard Sentry
  2. Clique “Slack”
  3. Autorize seu workspace
  4. 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/catch ou 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étricaAntesDepoisMelhora
Taxa de erro descoberto0~50-100/dia100% visibility
Bounce rate18%16%-2%
Session duration3m 40s3m 58s+4.8%
Conversão checkout3.2%3.8%+0.6%
Support emails sobre “site bugado”3-5/mês0-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

Próximo passo

Precisa de um dev que entrega de verdade?

Seja pra um projeto pontual, reforço no time, ou parceria de longo prazo. Vamos conversar.

Falar no WhatsApp

Respondo em até 2h durante horário comercial.