Closes #88: financial error taxonomy and Spanish copy consistency#93
Closes #88: financial error taxonomy and Spanish copy consistency#93Kalebtron1 wants to merge 1 commit into
Conversation
…ency - Add errorMessages.js with full error taxonomy per category - Add errorMap.js with HTTP/domain mapping and resolveErrorMessage() - Normalize useQRScanner to avoid raw exceptions reaching the UI - Fix visible technical copy in TradeCancelled (trade, escrow) - Update critical screens: auth, map, chat, QR, detail, refund, dispute Closes ericmt-98#88 Depends on ericmt-98#69
|
@Kalebtron1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR standardizes frontend error messaging via a centralized error map/messages system and updates UI copy to consistently use Spanish product terminology (e.g., “operación”, “garantía”, “comerciante”).
Changes:
- Added
errorMessages+resolveErrorMessage()mapping to normalize error titles/messages/actions. - Updated several pages/components/hooks to use the new resolver and refreshed Spanish UX copy.
- Replaced “trade/escrow/agent” wording across the UI with “operación/garantía/comerciante” equivalents.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| micopay/frontend/src/utils/apiError.ts | Routes API/Axios errors through resolveErrorMessage() during normalization. |
| micopay/frontend/src/pages/TradeDetail.tsx | Uses centralized error copy for error screens + copy updates (“garantía”). |
| micopay/frontend/src/pages/TradeCancelled.tsx | Copy updates: “operación/garantía/bloqueo”. |
| micopay/frontend/src/pages/Terms.tsx | Copy updates replacing “trade/fees”. |
| micopay/frontend/src/pages/SuccessScreen.tsx | Share text + UI copy updated (“Operación”, “Bloqueo/Liberación”). |
| micopay/frontend/src/pages/QRReveal.tsx | Copy updates (“Garantía”, “operación”). |
| micopay/frontend/src/pages/Profile.tsx | Replaces ad-hoc error strings with resolveErrorMessage(). |
| micopay/frontend/src/pages/Privacy.tsx | Copy updates (“operaciones”). |
| micopay/frontend/src/pages/MerchantSettings.tsx | Uses resolveErrorMessage() for load/save failures + copy updates. |
| micopay/frontend/src/pages/MerchantInbox.tsx | Copy updates (“operaciones”). |
| micopay/frontend/src/pages/Home.tsx | Copy update (“saldo”). |
| micopay/frontend/src/pages/ExploreMap.tsx | Copy updates (“garantía”, “operaciones”). |
| micopay/frontend/src/pages/Explore.tsx | Copy updates + localized alt text/footer. |
| micopay/frontend/src/pages/DepositRequest.tsx | Copy updates (“comerciantes”, “opciones”). |
| micopay/frontend/src/pages/DepositQR.tsx | Copy updates (“comerciante”, “billetera”). |
| micopay/frontend/src/pages/DepositChat.tsx | Copy updates (“garantía”). |
| micopay/frontend/src/pages/ClaimQR.tsx | Uses resolveErrorMessage() for fetch errors + copy updates (“comerciante”). |
| micopay/frontend/src/pages/ChatRoom.tsx | Copy updates (“garantía”, “operación”). |
| micopay/frontend/src/pages/CashoutRequest.tsx | Copy updates (“comerciantes”, “opciones”). |
| micopay/frontend/src/pages/CETESScreen.tsx | Copy updates (“rendimiento”, “operación”). |
| micopay/frontend/src/pages/BlendScreen.tsx | Copy updates (“operación”, “explorador”, “fondos”). |
| micopay/frontend/src/hooks/useQRScanner.ts | Uses resolveErrorMessage() for scanner permission/support/failure errors + prompt copy update. |
| micopay/frontend/src/hooks/useGeolocation.ts | Copy refinements for geolocation error strings. |
| micopay/frontend/src/constants/errorMessages.js | New centralized Spanish error copy catalog (title/message/action). |
| micopay/frontend/src/constants/errorMap.js | New mapping/resolver from status/domain/message to errorMessages entries. |
| micopay/frontend/src/components/TradeStateBadge.tsx | Copy updates (“operación”, “garantía”). |
| micopay/frontend/src/components/TradeConfirmation.tsx | Copy updates (“operación”, “garantía”, “comerciante”). |
| micopay/frontend/src/components/SupportLink.tsx | Mailto subject/body copy updates (“Operación ID”). |
| micopay/frontend/src/components/MerchantUnavailableBanner.tsx | Localizes banner strings to Spanish + “operación”. |
| micopay/frontend/src/components/ErrorBoundary.tsx | Uses resolveErrorMessage() to render structured title/message/action/safety. |
| micopay/frontend/src/components/ConnectionBanner.tsx | Localizes default reconnect text via string comparison. |
| micopay/frontend/src/components/CancelTradeDialog.tsx | Copy updates (“operación/garantía”). |
Comments suppressed due to low confidence (1)
micopay/frontend/src/utils/apiError.ts:1
- The
messageselection logic is currently broken/redundant: both branches returnresolved.message, so the condition has no effect and any non-empty backenddata.messageis effectively ignored. Either remove the conditional entirely (always useresolved.message) or prefer a valid backenddata.messagewhen present and fall back toresolved.messageotherwise.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try { | ||
| const res = await fetch(`${PROTOCOL_API}/api/v1/cash/request/${requestId}`); | ||
| if (!res.ok) { setError('Solicitud no encontrada'); return; } | ||
| if (!res.ok) { setError(resolveErrorMessage({ response: { status: res.status } }).message); return; } |
| }); | ||
| return { value: barcodes[0]?.rawValue ?? null }; | ||
| } catch (e) { | ||
| return { value: null, error: e instanceof Error ? e.message : 'Scan cancelado' }; | ||
| return { value: null, error: resolveErrorMessage({ message: 'scan_failed' }).message }; | ||
| } |
| if (!token) { | ||
| setLoading(false); | ||
| setError("No hay una cuenta autenticada para mostrar."); | ||
| setError(resolveErrorMessage({ response: { status: 401 } }).message); |
| <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> | ||
| </svg> | ||
| <p className="font-bold">{message}</p> | ||
| <p className="font-bold">{message === 'Reconnecting...' ? 'Reconectando…' : message}</p> |
|
@ericmt-98 please review or close |
#88 — Financial Error Taxonomy and Spanish Copy Consistency
What does this PR do?
Centralizes all app error messages into clear, actionable Spanish copy,
eliminates technical strings visible to the user, and unifies financial
terminology across the interface. micopay serves rural and non-technical
users in Mexico — an error like "ConflictError" or "Backend not available"
doesn't tell them what happened, whether their money is safe, or what to do next.
Main changes
New files
src/constants/errorMessages.js— full error taxonomy in Spanish withtitle,message,actionandfundsSafeper categorysrc/constants/errorMap.js— HTTP status/domain mapping to taxonomy keysplus
resolveErrorMessage(error)utility functionModified files
src/utils/apiError.ts— now uses the resolver to produce UI-safe messagessrc/components/ErrorBoundary.tsx— renderstitle,message,actionand
fundsSafenote from the taxonomysrc/hooks/useQRScanner.ts— camera and scan errors now go through theresolver instead of exposing raw exception text
src/pages/TradeCancelled.tsx— removed last visible uses of "trade"and "escrow" in user-facing copy
TradeDetail,ExploreMap,Profile,ClaimQR,MerchantInbox, auth, refund and dispute flowsUnified terminology
What was tested
get_errorsafter each modified fileresolveErrorMessage()andQR keys (
cameraDenied,scanFailed) exist and map correctlyto confirm no technical error names are rendered
Acceptance criteria
fundsSafe)Known debt (out of scope)
.messagefrom the resolver, hidingtitle,actionand thefundsSafenote — affectsProfile,MerchantSettings,ClaimQRerror view anduseQRScannerconsumersSoroban HTLC,hash de reembolso,USDC— should be softened fornon-technical users in a follow-up
Home.tsx,History.tsx,DepositMap.tsx) remainshardcoded — proposed as a separate issue for full i18n readiness
Closes #88 — Depends on #69