<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x" -->

---
title: New in Symfony 8.2: Recovering from Controller Attribute...
description: Symfony 8.2 lets controllers recover from failed attribute checks instead of an error response. Add a nullable argument typed with the attribute's exception,...
canonical: https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: New in Symfony 8.2: Recovering from Controller Attribute Failures (Symfony Blog) | daily.dev
og:description: Symfony 8.2 lets controllers recover from failed attribute checks instead of an error response. Add a nullable argument typed with the attribute's exception,...
og:url: https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x
og:image: https://api.daily.dev/og/posts/CaKEnjU9x.png
og:image:alt: New in Symfony 8.2: Recovering from Controller Attribute Failures (Symfony Blog)
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# New in Symfony 8.2: Recovering from Controller Attribute Failures (Symfony Blog)

**[Symfony](https://daily.dev/sources/symfony)** · 2 min read · 0 upvotes · 0 comments

## Summary

Symfony 8.2 lets controllers recover from failed attribute checks instead of an error response. Add a nullable argument typed with the attribute's exception, such as SignedUriException for #[IsSignatureValid], and Symfony passes the exception to it when the check fails. You can type a subclass like ?ExpiredSignedUriException to handle only expired links, or a union type to catch failures from multiple attributes like #[IsCsrfTokenValid] and #[RateLimit] in one argument. #[IsGranted] is excluded from this behavior because forgetting the check would let users run actions they aren't allowed to. Custom attributes can opt in with the new #[RecoverableAttribute].

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://symfony.com/blog/new-in-symfony-8-2-recovering-from-controller-attribute-failures>

## Questions this post answers

### How do I handle an expired signed URL in Symfony 8.2 instead of showing an error page?

Add a nullable argument typed with the SignedUriException to the controller method using #[IsSignatureValid]. Symfony passes the exception to that argument when the check fails and still calls the controller, letting you add a flash message and redirect instead of showing an error response. Use the subclass ?ExpiredSignedUriException to handle only expired links specifically.

_Track new Symfony 8.2 controller features like this on daily.dev as you plan the upgrade._

### Can one controller argument catch failures from multiple Symfony attributes like IsCsrfTokenValid and RateLimit?

Yes, by typing the nullable recovery argument as a union of exception types, such as InvalidCsrfTokenException|RateLimitExceededException|null. Symfony passes whichever exception triggered the failure into that argument, and you can use a match expression on instanceof checks to show different flash messages per failure type before redirecting.

_Developers weighing Symfony's new attribute recovery patterns can follow the details on daily.dev._

### Why doesn't Symfony's #[IsGranted] attribute let controllers recover from authorization failures?

Symfony deliberately excludes #[IsGranted] from the new recoverable attribute behavior introduced in version 8.2. Allowing controllers to catch its failure exception would risk a developer forgetting to check the argument, letting unauthorized users run actions they shouldn't be allowed to perform.

_Anyone hardening authorization logic in Symfony can keep up with changes like this via daily.dev._

## Similar posts on daily.dev

- [New in Symfony 8.1: Dynamic Controller Attributes \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-1-dynamic-controller-attributes-symfony-blog--p1eaqpp8q) · Symfony · 4 upvotes · 0 comments
- [New in Symfony 7.4: Attribute Improvements \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-7-4-attribute-improvements-symfony-blog--0dftx5qrt) · Symfony · 0 upvotes · 0 comments
- [New in Symfony 8.2: Locking Controllers \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-2-locking-controllers-symfony-blog--mkwvfc60j) · Symfony · 14 upvotes · 0 comments
- [New in Symfony 8.2: Single-Use and Safer Signed URLs \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-2-single-use-and-safer-signed-urls-symfony-blog--gw7pmz8l4) · Symfony · 1 upvotes · 0 comments
- [New in Symfony 8.2: Attribute-Based Workflows \(Symfony Blog\)](https://daily.dev/posts/new-in-symfony-8-2-attribute-based-workflows-symfony-blog--8gja5a6ri) · Symfony · 2 upvotes · 0 comments

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#php](https://daily.dev/tags/php), [#symfony](https://daily.dev/tags/symfony)

[View this post on daily.dev](https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"New in Symfony 8.2: Recovering from Controller Attribute Failures (Symfony Blog)","url":"https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x"},"datePublished":"2026-10-30T11:10:26.033Z","dateModified":"2026-10-30T11:10:54.032Z","description":"Symfony 8.2 lets controllers recover from failed attribute checks instead of an error response. Add a nullable argument typed with the attribute's exception,...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/327b244859fddae8f3a20d0225898aa0?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/327b244859fddae8f3a20d0225898aa0?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Symfony","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Symfony","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/cc07051b7112472f9729e73c14660a64","url":"https://daily.dev/sources/symfony"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"webdev,php,symfony","timeRequired":"PT2M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Symfony","item":"https://daily.dev/sources/symfony"},{"@type":"ListItem","position":3,"name":"New in Symfony 8.2: Recovering from Controller Attribute Failures (Symfony Blog)"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/new-in-symfony-8-2-recovering-from-controller-attribute-failures-symfony-blog--cakenju9x#faq","mainEntity":[{"@type":"Question","name":"How do I handle an expired signed URL in Symfony 8.2 instead of showing an error page?","acceptedAnswer":{"@type":"Answer","text":"Add a nullable argument typed with the SignedUriException to the controller method using #[IsSignatureValid]. Symfony passes the exception to that argument when the check fails and still calls the controller, letting you add a flash message and redirect instead of showing an error response. Use the subclass ?ExpiredSignedUriException to handle only expired links specifically. Track new Symfony 8.2 controller features like this on daily.dev as you plan the upgrade."}},{"@type":"Question","name":"Can one controller argument catch failures from multiple Symfony attributes like IsCsrfTokenValid and RateLimit?","acceptedAnswer":{"@type":"Answer","text":"Yes, by typing the nullable recovery argument as a union of exception types, such as InvalidCsrfTokenException|RateLimitExceededException|null. Symfony passes whichever exception triggered the failure into that argument, and you can use a match expression on instanceof checks to show different flash messages per failure type before redirecting. Developers weighing Symfony's new attribute recovery patterns can follow the details on daily.dev."}},{"@type":"Question","name":"Why doesn't Symfony's #[IsGranted] attribute let controllers recover from authorization failures?","acceptedAnswer":{"@type":"Answer","text":"Symfony deliberately excludes #[IsGranted] from the new recoverable attribute behavior introduced in version 8.2. Allowing controllers to catch its failure exception would risk a developer forgetting to check the argument, letting unauthorized users run actions they shouldn't be allowed to perform. Anyone hardening authorization logic in Symfony can keep up with changes like this via daily.dev."}}]}
```

