fix(layers): report Directions errors as English data

The Directions row errors (pointer blocked, no route, routing timed out,
no response from the routing service) and the route request failures
("Routing failed: {error}", "{error} — try again in a moment",
"Routing unavailable (HTTP {status})", the rate-limit and fallback
texts) were translated inside getStats(), so the layer snapshot that
voice tools and the analyst read carried Spanish or Russian text.

Fixed texts are marked with msg() and the interpolated ones are built
in English. The Layers panel translates them where it shows them,
through a ROUTING_ERROR_PATTERNS block in statusText.js that the
proxy's refusal texts move into. English reads as before. In other
locales two things differ slightly: a proxy text inside "Routing
failed: X" that is not one of the known refusals is now looked up in
the catalog instead of shown as given, and the "— try again in a
moment" shape is recognised on every layer's error, not only on
Directions.
This commit is contained in:
daikaginza committed 2026-10-18 13:57:48 +07:00
1 parent 93ea088f45
commit 4d2a71c1b2
4 files changed
+194 -44

No files matched your search

+19 -32
View File
@@ -38,33 +38,21 @@ export const DIRECTIONS_MODES = Object.freeze({
export const DEFAULT_DIRECTIONS_MODE = 'car';
/**
* The route proxy's refusal texts (server/providers/places/routes.js). They
* stay English on the wire and in the AI tools; the row shows them translated.
* The row error for a failed route request (createDirectionsSource errors),
* as English data; the Layers panel shows it translated (ROUTING_ERROR_PATTERNS
* in src/ui/statusText.js).
*/
const ROUTING_REFUSALS = new Set([
msg('rate limited'),
msg('routing service is rate limited'),
msg('route leg too long'),
msg('route too long'),
]);
/** A refusal text from the route proxy in the language; unknown ones as given. */
export function presentRoutingRefusal(text) {
return ROUTING_REFUSALS.has(text) ? t(text) : text;
}
/** The row text for a failed route request (createDirectionsSource errors). */
export function presentRoutingFailure(error) {
if (error?.status === 429) {
return error.refusal
? t('{error} — try again in a moment', {
error: presentRoutingRefusal(error.refusal),
})
: t('Routing is rate limited — try again in a moment');
? // i18n-ignore: English data, shown through ROUTING_ERROR_PATTERNS
`${error.refusal} — try again in a moment`
: msg('Routing is rate limited — try again in a moment');
}
if (Number.isFinite(error?.status) && error.status > 0)
return t('Routing unavailable (HTTP {status})', { status: error.status });
return error?.message || t('Routing unavailable');
// i18n-ignore: English data, shown through ROUTING_ERROR_PATTERNS
return `Routing unavailable (HTTP ${error.status})`;
return error?.message || msg('Routing unavailable');
}
/** Route colour — the annotation palette's cyan, so voice routes and Directions match. */
@@ -643,7 +631,9 @@ export function directionsStats(state) {
return {
count: route?.steps.length || 0,
lastUpdate,
error: t('Another map tool is using clicks — close it, then SET A again'),
error: msg(
'Another map tool is using clicks — close it, then SET A again',
),
status: 'empty',
source,
};
@@ -662,7 +652,7 @@ export function directionsStats(state) {
return {
count: 0,
lastUpdate,
error: error || t('No route found'),
error: error || msg('No route found'),
status: 'empty',
source,
};
@@ -1144,13 +1134,10 @@ export function createDirectionsLayer({ services, source }) {
clearRouteGraphics();
_status = 'error';
_error =
payload?.error === 'no route found'
? t('No route found between A and B')
: payload?.error
? t('Routing failed: {error}', {
error: presentRoutingRefusal(payload.error),
})
: t('No route found between A and B');
// i18n-ignore: English data, shown through ROUTING_ERROR_PATTERNS
payload?.error && payload.error !== 'no route found'
? `Routing failed: ${payload.error}`
: msg('No route found between A and B');
return;
}
_route = route;
@@ -1167,9 +1154,9 @@ export function createDirectionsLayer({ services, source }) {
// happened instead.
_error =
error?.name === 'AbortError'
? t('Routing timed out')
? msg('Routing timed out')
: error?.name === 'TypeError'
? t('Routing unavailable — no response from the routing service')
? msg('Routing unavailable — no response from the routing service')
: presentRoutingFailure(error);
} finally {
clearTimeout(timer);