fix(dispatch): 接單/取消「當下做不到」改回 409,不再用 200+文案(T1) - #64
Merged
Conversation
先前 AcceptRide 對「已被別人接走」「非待命狀態」、cancelActiveRide 對「行程已開始」 「狀態已變更」回的都是 (訊息, nil),HTTP 層照樣送 200。 **任何只看有沒有丟例外的客戶端都會把失敗當成成功**——沒搶到的司機拿到一張完整但假的 行程卡,開去接一個不存在的乘客;乘客按了取消卻什麼也沒發生,畫面上那張單還在。 - 新增四個 sentinel error:ErrRideTaken/ErrDriverNotIdle/ErrRideStarted/ ErrRideStateChanged,service 改回錯誤而非 (訊息, nil)。 - readStatusForErr 補上這四個 → 409(先前落到 default 會變 500,而這些文案是要 原樣顯示給使用者的)。**文案一字未改**——LINE 與 App 都直接顯示它。 - LINE webhook 的客戶取消改回原文案,不再一律「取消失敗,請稍後再試」 (那會讓人一直重試一件永遠不會成功的事)。 - 順手修掉測試 helper 的寫死車牌(同一個測試建兩位司機會被唯一約束擋下)。 驗收:新增 dispatch_conflict_test.go 三案+更新既有「已上車不可取消」那案, go test ./internal/handler ./internal/notify 綠。 實跑(本機 server):重複接單 → 409「手慢了…」、已上車後取消 → 409「行程已開始…」; 改之前兩者都是 200。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
問題(本檔 T 章的 T1,掛在待處理很久)
AcceptRide對「已被別人接走」「非待命狀態」、cancelActiveRide對「行程已開始」「狀態已變更」回的都是
(訊息, nil)—— HTTP 層照樣送 200。任何只看有沒有丟例外的客戶端都會把失敗當成成功:
App 端為此長出一條退路(接單後一律重讀
rides/active、以後端有沒有這張單判定成敗)——多打一支 API 才換得到正確性。
做了什麼
ErrRideTaken/ErrDriverNotIdle/ErrRideStarted/ErrRideStateChanged;service 改回錯誤而非(訊息, nil)。readStatusForErr補上這四個 → 409。先前它們會落到 default 變 500,而這些文案是要原樣顯示給使用者的
(「行程已開始,無法取消」變成「伺服器發生錯誤」,乘客不知道自己該做什麼)。
(那會讓人一直重試一件永遠不會成功的事)。
驗收
dispatch_conflict_test.go三案(已被接走/非待命/狀態已變更),並把既有「已上車不可取消」那案從「比對訊息字串」改成
errors.Is。go test ./internal/handler ./internal/notify綠。go run ./cmd/server):409 {"error":"手慢了,這單已被其他司機接走"}409 {"error":"行程已開始,無法取消"}App 端要不要改?
不用。App 現行行為在 409 下更好:
acceptOffer會顯示後端文案,接單卡由後端的ride.taken事件收掉(T2 已上線);乘客端cancelOrder本來就把ApiException.message顯示出來——先前 200 時它反而什麼都不說。既有的「逾時才對帳」退路留著仍然無害。
🤖 Generated with Claude Code