fix(booking): 交易內只攔截業務例外,資料庫錯誤改交由例外處理器
新增 BookingRuleViolationException,MemberBookingController::store 與 ProviderBookingController::confirm 只 catch 此型別並回 422(訊息不變)。 QueryException 等其他例外不再被當成 422 回傳 SQL,改由 Laravel 回 500 並回報 Sentry。對應 OpenSpec change fix-booking-exception-handling(M7)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Enums\BookingStatus;
|
||||
use App\Enums\ScheduleStatus;
|
||||
use App\Exceptions\BookingRuleViolationException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Booking;
|
||||
use App\Models\CourseSchedule;
|
||||
@@ -68,7 +69,7 @@ class MemberBookingController extends Controller
|
||||
// Layer 2:lockForUpdate 後二次驗證
|
||||
$schedule = CourseSchedule::lockForUpdate()->find($schedule->id);
|
||||
if ($data['participants'] > $schedule->remainingSpots()) {
|
||||
throw new \RuntimeException('名額不足,請重新選擇');
|
||||
throw new BookingRuleViolationException('名額不足,請重新選擇');
|
||||
}
|
||||
|
||||
// 重複預約檢查
|
||||
@@ -77,7 +78,7 @@ class MemberBookingController extends Controller
|
||||
->whereIn('status', [BookingStatus::Pending->value, BookingStatus::Confirmed->value])
|
||||
->exists();
|
||||
if ($duplicate) {
|
||||
throw new \RuntimeException('您已預約此時段');
|
||||
throw new BookingRuleViolationException('您已預約此時段');
|
||||
}
|
||||
|
||||
return Booking::create([
|
||||
@@ -89,7 +90,7 @@ class MemberBookingController extends Controller
|
||||
'notes' => $data['notes'] ?? null,
|
||||
]);
|
||||
});
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (BookingRuleViolationException $e) {
|
||||
return response()->json(['status' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Enums\BookingStatus;
|
||||
use App\Enums\ScheduleStatus;
|
||||
use App\Exceptions\BookingRuleViolationException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Booking;
|
||||
use App\Notifications\BookingCancelledNotification;
|
||||
@@ -43,7 +44,7 @@ class ProviderBookingController extends Controller
|
||||
$remaining = $schedule->max_participants - $schedule->current_participants;
|
||||
|
||||
if ($booking->participants > $remaining) {
|
||||
throw new \RuntimeException('名額不足,無法確認此預約');
|
||||
throw new BookingRuleViolationException('名額不足,無法確認此預約');
|
||||
}
|
||||
|
||||
$booking->update(['status' => BookingStatus::Confirmed]);
|
||||
@@ -54,7 +55,7 @@ class ProviderBookingController extends Controller
|
||||
$schedule->update(['status' => ScheduleStatus::Full]);
|
||||
}
|
||||
});
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (BookingRuleViolationException $e) {
|
||||
return response()->json(['status' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user