feat: improved error handling and redirect on invalid session

This commit is contained in:
Björn Fromme
2026-03-16 12:00:55 +01:00
parent 4b95b12a7b
commit a6d2661562
7 changed files with 48 additions and 12 deletions
@@ -138,7 +138,8 @@ class IndexController extends AbstractController
return $this->redirectToRoute('app_account');
}
return $this->redirect($returnUrl);
// Use htmxRedirect for cross-origin safety (returnUrl may be external)
return $this->htmxRedirect($request, $returnUrl);
}
return $this->render('booking/modal_cancel.html.twig');
@@ -108,6 +108,7 @@ class Step2Controller extends AbstractController
'bookingDto' => $bookingCreateDto,
'cardsData' => $cardsData,
'summaryData' => $summaryData,
'isSubmitted' => $form->isSubmitted(),
];
return $this->render('booking/create/step_2.html.twig', $templateData);
@@ -123,7 +124,11 @@ class Step2Controller extends AbstractController
)]
public function editParticipant(int $index, Request $request): Response
{
$bookingDto = $this->loadBookingDtoOrFail($request, BookingDto::MODE_CREATE);
$result = $this->loadBookingDtoOrRedirect($request, BookingDto::MODE_CREATE);
if ($result instanceof Response) {
return $result;
}
$bookingDto = $result;
// Validate participant index
if (false === isset($bookingDto->participants[$index])) {
@@ -178,7 +183,11 @@ class Step2Controller extends AbstractController
)]
public function refreshParticipantForm(int $index, Request $request): Response
{
$bookingDto = $this->loadBookingDtoOrFail($request, BookingDto::MODE_CREATE);
$result = $this->loadBookingDtoOrRedirect($request, BookingDto::MODE_CREATE);
if ($result instanceof Response) {
return $result;
}
$bookingDto = $result;
// Validate participant index
if (false === isset($bookingDto->participants[$index])) {
@@ -34,7 +34,7 @@ trait BookingExceptionHandlerTrait
try {
return $bookingService->getOrCreateBookingCreateDto($request);
} catch (BookingSessionNotFoundException $e) {
$this->addFlash('error', 'Ihre Buchungssitzung ist abgelaufen. Bitte starten Sie eine neue Buchung.');
$this->addFlash('error', 'Deine Buchungssitzung ist abgelaufen. Bitte starte eine neue Buchung.');
return $this->redirectToRoute('app_booking_create_error');
} catch (TravelNotFoundException $e) {
@@ -8,6 +8,7 @@ use App\Form\BookingParticipantType;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantEditDto;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -20,16 +21,18 @@ use Symfony\Component\HttpFoundation\Response;
trait ParticipantCardFlowTrait
{
/**
* Load BookingDto from session or throw exception.
* Load BookingDto from session or return redirect to login.
*
* @throws \RuntimeException When booking data not found in session
* Returns RedirectResponse when session data is missing (e.g., after cancel or session expiry).
*/
private function loadBookingDtoOrFail(Request $request, string $mode): BookingDto
private function loadBookingDtoOrRedirect(Request $request, string $mode): BookingDto|RedirectResponse
{
$bookingDto = $this->bookingService->getBookingDto($request, $mode);
if (null === $bookingDto) {
throw new \RuntimeException(sprintf('Booking data not found in session for mode: %s', $mode));
$this->addFlash('info', 'Deine Sitzung ist abgelaufen. Bitte starte eine neue Buchung.');
return $this->redirectToRoute('app_login');
}
return $bookingDto;
@@ -183,4 +186,6 @@ trait ParticipantCardFlowTrait
abstract private function render(string $view, array $parameters = [], ?Response $response = null): Response;
abstract protected function addFlash(string $type, mixed $message): void;
abstract protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse;
}