mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-09-16 01:33:09 +00:00
Merge PR #508: различать устаревшего бота и ненастроенного на логине
404 на /cabinet/branding/telegram-widget и deeplink-роутах = сборка бота старше v3.24/v3.33 — вместо «бот не настроен» показываем auth.botOutdated (4 локали). README: фактический минимум v3.33.0. Закрывает #345. Спасибо @kewldan.
This commit is contained in:
59
src/utils/api-error.test.ts
Normal file
59
src/utils/api-error.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { AxiosError, AxiosHeaders } from 'axios';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getApiErrorMessage, isEndpointMissingError } from './api-error';
|
||||
|
||||
function axiosErrorWithStatus(status: number, detail?: unknown): AxiosError {
|
||||
const headers = new AxiosHeaders();
|
||||
const config = { headers };
|
||||
return new AxiosError(
|
||||
'Request failed',
|
||||
'ERR_BAD_REQUEST',
|
||||
config,
|
||||
{},
|
||||
{
|
||||
status,
|
||||
statusText: '',
|
||||
headers,
|
||||
config,
|
||||
data: detail === undefined ? {} : { detail },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
describe('isEndpointMissingError', () => {
|
||||
it('returns true for an axios 404', () => {
|
||||
expect(isEndpointMissingError(axiosErrorWithStatus(404))).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for other axios statuses', () => {
|
||||
expect(isEndpointMissingError(axiosErrorWithStatus(403))).toBe(false);
|
||||
expect(isEndpointMissingError(axiosErrorWithStatus(500))).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for non-axios errors', () => {
|
||||
expect(isEndpointMissingError(new Error('boom'))).toBe(false);
|
||||
expect(isEndpointMissingError(undefined)).toBe(false);
|
||||
expect(isEndpointMissingError(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getApiErrorMessage', () => {
|
||||
it('returns string detail from an axios error', () => {
|
||||
expect(getApiErrorMessage(axiosErrorWithStatus(400, 'Code must not be empty'), 'fb')).toBe(
|
||||
'Code must not be empty',
|
||||
);
|
||||
});
|
||||
|
||||
it('joins pydantic validation errors', () => {
|
||||
const err = axiosErrorWithStatus(422, [
|
||||
{ loc: ['body', 'name'], msg: 'field required' },
|
||||
{ loc: ['body', 'days'], msg: 'must be positive' },
|
||||
]);
|
||||
expect(getApiErrorMessage(err, 'fb')).toBe('name: field required; days: must be positive');
|
||||
});
|
||||
|
||||
it('falls back for non-axios errors and missing detail', () => {
|
||||
expect(getApiErrorMessage(new Error('boom'), 'fb')).toBe('fb');
|
||||
expect(getApiErrorMessage(axiosErrorWithStatus(500), 'fb')).toBe('fb');
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,15 @@
|
||||
import axios from 'axios';
|
||||
|
||||
/**
|
||||
* True when the backend answered 404 on the route itself — for cabinet
|
||||
* endpoints that means the bot build is too old to have them (e.g. the
|
||||
* deep-link auth routes exist only since bot v3.33.0), as opposed to a
|
||||
* missing entity inside a handler.
|
||||
*/
|
||||
export function isEndpointMissingError(err: unknown): boolean {
|
||||
return axios.isAxiosError(err) && err.response?.status === 404;
|
||||
}
|
||||
|
||||
export function getApiErrorMessage(err: unknown, fallback: string): string {
|
||||
if (axios.isAxiosError(err)) {
|
||||
const detail = err.response?.data?.detail;
|
||||
|
||||
Reference in New Issue
Block a user