Publicado em

- 7 minutos de leitura

Error Boundary no Angular 22.2: conheça @boundary e @error

img of Error Boundary no Angular 22.2: conheça @boundary e @error

Um erro de renderização em um componente pode comprometer uma parte grande da interface. Até agora, o Angular encaminhava esse problema ao ErrorHandler, mas a aplicação não tinha uma sintaxe declarativa para isolar a falha e mostrar uma alternativa no mesmo ponto da tela.

O Angular 22.2 muda esse cenário com os blocos @boundary e @error. A ideia é proteger uma região do template: se algo falhar durante a inicialização ou a detecção de mudanças, o Angular remove a view com problema e renderiza uma interface de fallback.

No momento da publicação deste artigo, o Angular 22.2.0-rc.0 já está disponível e a versão estável deve ser lançada nos próximos dias. O Error Boundary está marcado como Developer Preview, portanto sua API ainda pode receber ajustes antes de se tornar estável.

Para acompanhar o recurso em funcionamento, recomendo o vídeo abaixo:

Se preferir, assista o vídeo diretamente no YouTube:

O problema que o Error Boundary resolve

Imagine um dashboard com gráfico, resumo financeiro e lista de transações. Se o componente do gráfico lançar uma exceção durante a renderização, não faz sentido perder o restante da página.

O Error Boundary cria um limite ao redor da parte mais vulnerável:

   @boundary {
<app-revenue-chart [data]="chartData()" />
} @error {
<div class="chart-fallback">
	<p>Não foi possível exibir o gráfico.</p>
</div>
}

O conteúdo dentro de @boundary é a view principal. Se um componente ou uma diretiva nessa região lançar um erro durante a inicialização, renderização ou detecção de mudanças, o Angular substitui esse conteúdo pelo bloco @error.

O restante do template continua funcionando:

   <main>
	<app-account-summary />

	@boundary {
	<app-revenue-chart [data]="chartData()" />
	} @error {
	<p>O gráfico está indisponível.</p>
	}

	<app-recent-transactions />
</main>

Nesse exemplo, a falha fica restrita ao gráfico. O resumo da conta e as transações permanecem visíveis e interativos.

Quais erros são capturados

A documentação do Angular define o recurso para erros que acontecem durante a renderização e a detecção de mudanças. Os testes do framework incluem falhas em:

  • Construtores de componentes.
  • Hooks como ngOnInit e ngOnChanges.
  • Expressões e bindings do template.
  • Views criadas por blocos como @if e @for.
  • Effects associados à view protegida.
  • Componentes e diretivas descendentes do bloco.

O limite não transforma qualquer falha da aplicação em fallback visual. Um erro de HttpClient tratado em um Observable, uma Promise rejeitada ou uma validação de negócio continuam pedindo tratamento no ponto em que ocorrem. O @boundary entra em ação quando a exceção alcança o processo de criação ou atualização da view.

Isso mantém uma separação útil: estados esperados, como uma API indisponível, podem ser representados no próprio modelo da tela. Exceções inesperadas durante a renderização ficam contidas pelo Error Boundary.

Acessando o erro com $error

O bloco @error recebe a variável implícita $error:

   @boundary {
<app-payment-summary />
} @error {
<h2>Não foi possível carregar o pagamento</h2>
<p>{{ $error.message }}</p>
}

Também é possível criar um nome local para deixar o template mais legível:

   @boundary {
<app-payment-summary />
} @error (let error) {
<h2>Não foi possível carregar o pagamento</h2>
<p>{{ error.message }}</p>
}

Exibir error.message ajuda durante o desenvolvimento. Em produção, prefira uma mensagem curta para o usuário e envie os detalhes técnicos ao serviço de observabilidade. Mensagens internas podem conter dados que não deveriam aparecer na interface.

Imagem com o texto: Curso Angular Moderno e um homem de pele parda usando óculos com a logo do Angular atrás. Logo abaixo existe um botão com o texto "Eu quero!"

Tentando novamente com $reset

O bloco de fallback também possui a função $reset. Ela limpa o estado do boundary e tenta renderizar a view principal outra vez:

   @boundary {
<app-live-report />
} @error {
<div role="alert">
	<p>O relatório não pôde ser exibido.</p>
	<button type="button" (click)="$reset()">Tentar novamente</button>
</div>
}

Você pode criar um alias para a função:

   @boundary {
<app-live-report />
} @error (let error; reset = $reset) {
<p>Falha ao renderizar: {{ error.message }}</p>
<button type="button" (click)="reset()">Tentar novamente</button>
}

O reset não corrige a origem da exceção. Se o estado continuar inválido, a nova tentativa falhará e o fallback será exibido novamente. Esse botão funciona melhor quando a causa pode ter mudado, como um recurso temporariamente indisponível ou uma dependência carregada de forma dinâmica.

Fallbacks diferentes com when

Um boundary pode possuir vários blocos @error. A cláusula when decide qual deles atende ao erro capturado:

   export class Checkout {
	isPaymentError(error: unknown): error is PaymentRenderError {
		return error instanceof PaymentRenderError
	}
}
   @boundary {
<app-payment-summary />
} @error (let error; reset = $reset; when isPaymentError(error)) {
<h2>O resumo do pagamento está indisponível</h2>
<button type="button" (click)="reset()">Tentar novamente</button>
} @error {
<h2>Ocorreu um erro inesperado</h2>
}

O Angular avalia os blocos na ordem em que aparecem e usa o primeiro when que retornar true. Coloque as condições específicas antes do fallback genérico.

O último @error sem when funciona como um caso padrão. Sem esse bloco, um erro que não atender a nenhuma condição continua subindo pela árvore.

Boundaries podem ser aninhados

Uma página pode usar um boundary para cada área independente e outro em um nível mais alto:

   @boundary {
<app-dashboard-header />

@boundary {
<app-analytics-chart />
} @error {
<p>O gráfico está indisponível.</p>
}

<app-dashboard-feed />
} @error {
<p>Não foi possível abrir o dashboard.</p>
}

O boundary interno trata primeiro os erros do gráfico. Se o próprio bloco @error falhar, a exceção segue para o boundary externo. Sem um limite acima dele, o Angular trata a falha como um erro não capturado da aplicação.

Essa composição permite colocar o fallback perto do contexto que ele representa. Um gráfico pode ter uma mensagem própria, enquanto uma falha estrutural do dashboard recebe uma alternativa mais ampla.

Integração com o ErrorHandler

Capturar o erro visualmente não significa ignorá-lo. O Angular 22.2 adiciona o hook opcional onViewError ao ErrorHandler para registrar erros interceptados por boundaries.

   import { ErrorDetails, ErrorHandler, Injectable } from '@angular/core'

@Injectable()
export class AppErrorHandler implements ErrorHandler {
	handleError(error: unknown): void {
		console.error('Erro não capturado', error)
	}

	onViewError(error: Error, details: ErrorDetails): void {
		console.error('Erro capturado por um boundary', {
			error,
			component: details.declarationType.name,
			boundary: details.boundary?.type.name
		})
	}
}

Registre o handler na configuração da aplicação:

   import { ApplicationConfig, ErrorHandler } from '@angular/core'
import { AppErrorHandler } from './app-error-handler'

export const appConfig: ApplicationConfig = {
	providers: [{ provide: ErrorHandler, useClass: AppErrorHandler }]
}

O objeto ErrorDetails informa a classe e a instância onde a falha ocorreu. Quando existe um boundary, ele também expõe o componente que declarou o limite e uma função reset.

Se o handler não implementar onViewError, o Angular encaminha o erro capturado para handleError. Assim, adicionar um fallback não remove o erro dos registros globais existentes.

Erros em componentes criados dinamicamente

O recurso também atende views criadas por código. ViewContainerRef.createComponent e createEmbeddedView, além da função standalone createComponent, recebem uma opção onError:

   const componentRef = viewContainerRef.createComponent(PluginWidget, {
	environmentInjector,
	onError: (error, details) => {
		console.error('Falha no plugin', {
			error,
			component: details.declarationType.name
		})
	}
})

Essa API é útil para plugins, widgets configuráveis e componentes carregados em tempo de execução. O callback permite registrar a falha e decidir como apresentar uma alternativa fora da sintaxe do template.

Onde colocar um Error Boundary

Evite envolver a aplicação inteira com um único boundary. Um fallback global pode impedir uma tela branca, mas oferece pouco contexto para recuperação.

Prefira limites em áreas que possam falhar de forma independente:

  • Dashboards e gráficos complexos.
  • Widgets de terceiros.
  • Editores ricos e visualizações de documentos.
  • Features carregadas dinamicamente.
  • Regiões que dependem de dados ou configurações pouco previsíveis.

Mantenha o fallback simples, acessível e com poucas dependências. Inclua um bloco genérico quando usar condições when, envie o erro para observabilidade e teste o caminho de reset.

Como a API está em Developer Preview, comece por regiões isoladas. Isso reduz o impacto caso a sintaxe mude em uma versão futura.

Como testar antes do lançamento estável

A versão 22.2.0-rc.0 está publicada sob a tag next. Se quiser experimentar o recurso antes da versão final, faça isso em uma branch separada:

   ng update @angular/core@next @angular/cli@next

Quando a versão estável estiver disponível, atualize os pacotes Angular para 22.2 seguindo o guia oficial de atualização:

   ng update @angular/core@22.2 @angular/cli@22.2

Mantenha as versões de @angular/core, compiler, CLI e demais pacotes oficiais alinhadas. Como o template usa uma sintaxe nova, o compilador do projeto precisa conhecer @boundary e @error.

Conclusão

O Error Boundary do Angular 22.2 permite que uma falha local receba uma resposta local. @boundary protege a região, @error apresenta o fallback, $error expõe a exceção e $reset tenta construir a view novamente.

Os filtros com when, os boundaries aninhados e o novo ErrorHandler.onViewError completam o fluxo. A interface continua utilizável e a equipe mantém os dados necessários para investigar o problema.

Comece por componentes que já representam fronteiras claras da aplicação. O recurso ainda está em Developer Preview, mas já oferece uma base prática para interfaces Angular mais resistentes a falhas de renderização.

Referências

Entre na nossa comunidade!

Receba novos posts, novidades do ecossistema Angular e muito mais.

Sobre o autor

Author's photo
Henrique Custódia Arquiteto Frontend, entusiasta Angular, cat lover, criador de conteúdo e fundador da Code Dimension!