Ошибки и лимиты
CardSdkError
Любой отказ — от приложения или от собственных проверок SDK ещё до того, как запрос покинет
карточку, — это CardSdkError:
import { CardSdkError, isCardSdkError } from '@neurosquad/card-sdk'
async function saveReport(text: string): Promise<void> {
try {
await card.fs.writeText('reports/latest.md', text, { createDirs: true })
} catch (error) {
if (isCardSdkError(error, 'PERMISSION_DENIED')) {
card.ui.toast(`This needs the ${error.permission} permission`)
} else if (isCardSdkError(error, 'RATE_LIMITED')) {
await new Promise((resolve) => setTimeout(resolve, error.retryAfterMs ?? 1000))
return saveReport(text)
} else if (error instanceof CardSdkError) {
card.log.error(error.code, error.method, error.hostMessage, error.data)
} else {
throw error
}
}
}| Свойство | Что это |
|---|---|
code | Один из кодов ниже. |
message | method: host message [CODE] — hint, готово для журнала. |
hostMessage | Только сообщение приложения (по-английски, для разработчиков — пользователям показывайте свой текст). |
method | Метод, который упал, если ошибка пришла из вызова. |
data | Подробности: ошибки схемы, { permission }, { retryAfterMs }, { conflict }… |
hint | Подсказка в одну строку — для кодов, у которых она есть. |
permission | Для PERMISSION_DENIED: недостающее разрешение. |
retryAfterMs | Для RATE_LIMITED: сколько ждать. |
issues | Для INVALID_PARAMS / BAD_REQUEST: { path, keyword, message }[] — где параметры не совпали со схемой. |
isCardSdkError(error, code?) — защитник типа, при желании для одного кода.
Коды ошибок
| Код | Значит | Обычно |
|---|---|---|
BAD_REQUEST | Сообщение повреждено или его параметры — не простой JSON. | В параметрах Date, Map или экземпляр класса — передавайте простые данные. |
INVALID_PARAMS | Параметры не подходят под схему метода. | Точный путь — в error.issues. А также значение порта, не прошедшее схему, или незаданный {{secret:…}}. |
METHOD_NOT_FOUND | Приложение не знает этот метод. | Старое приложение — проверяйте через card.host.supports(). |
PERMISSION_DENIED | У пакета нет разрешения. | Объявите его в манифесте или, если оно необязательное, попросите через card.permissions.request(). |
NOT_CONNECTED | Целевая карточка или агент не соединены с вашей стрелкой. | Попросите пользователя её провести. |
NOT_FOUND | Нет такой карточки, агента, ключа, файла или порта. | |
QUOTA_EXCEEDED | Квота исчерпана: байты или ключи хранилища, созданные карточки, наблюдатели за файлами, полная очередь промптов агента. | Удалите старые данные, остановите старых наблюдателей, подождите. |
RATE_LIMITED | Слишком много вызовов. Сколько ждать — в data.retryAfterMs. | Объединяйте вызовы, откладывайте, отступайте. (Заголовок, статус, бейдж, обзор и внимание из-за этого никогда не отклоняются — SDK схлопывает и повторяет их.) |
TOO_LARGE | Сообщение, значение или ответ больше лимита. | См. Лимиты. |
TIMEOUT | Нет ответа вовремя (запрос к порту, команда, сетевой запрос). | |
BUDGET_PAUSED | Воркспейс вышел за бюджет; программные промпты отклоняются. | Пользователь поднимает лимит в карточке Budget. |
BUSY | Агент посреди хода, а вы указали whenBusy: 'fail'. | |
HOST_NOT_ALLOWED | net.fetch к хосту вне выданных или к хосту, который резолвится в заблокированный адрес. | Добавьте хост в разрешение network. |
NETWORK_ERROR | Сбой DNS, соединения, TLS или потока. | |
FS_DENIED | Путь вне папки воркспейса, внутри .git/ или через ссылку, ведущую наружу. | Используйте относительный путь. |
FS_ERROR | Любая другая проблема с файлом; data.conflict, если не совпал ifMtimeMs. | |
NOT_VISIBLE | Нужно, чтобы карточка была на экране: диалоги, ссылки, полёт камеры, запросы разрешений, промпты агенту в опасном режиме. | Повторите, когда card.visibility === 'visible'. |
USER_CANCELLED | Пользователь отказался (подтверждение, промпт агенту в опасном режиме) или вызов отменён. | |
UNAVAILABLE | Цель не запущена, воркспейс не открыт, карточка усыплена или соединение закрыто. | |
PROTOCOL_MISMATCH | Карточка сделана под более новый протокол, чем знает приложение. | Пользователь обновляет NeuroSquad. |
NOT_READY | Вызов сделан до завершения рукопожатия. | Дождитесь connect(). |
INTERNAL | Ошибка в приложении. | Сообщите о ней, приложив журнал карточки. |
Лимиты
Все лимиты есть в card.limits (константа LIMITS из SDK). Дешёвые SDK проверяет до отправки;
приложение соблюдает все.
| Область | Лимит |
|---|---|
| Сообщения | до 1 МБ каждое (запросы fs.write и net.fetch и ответы fs.read, fs.list, net.fetch — до 12 МБ); до 64 вызовов одновременно (сверх этого SDK ставит их в очередь); 200 вызовов/с, всплески до 400; значения не глубже 64 уровней и не больше 200 000 узлов |
| Пакет | архив до 50 МБ; распакованный до 100 МБ; до 5 000 файлов; каждый до 20 МБ; пути до 240 символов и 20 уровней; манифест до 256 КБ; иконка до 128 КБ |
| Манифест | до 40 настроек; до 16 входов и 16 выходов; до 32 инструментов; до 32 сетевых хостов; схемы до 500 узлов и 16 уровней, enum до 256 вариантов и 16 КБ, const до 4 КБ |
| Хранилище | ключ до 256 символов; значение до 1 МБ; до 10 000 ключей; 5 МБ на карточку, 20 МБ на пакет |
| Сеть | тело до 5 МБ; ответ до 10 МБ; 6 одновременно; 120 в минуту; до 5 редиректов; тайм-аут 30 с (максимум 120 с), включая тело; до 4 потоков, каждый закрывается после 5 минут тишины или 256 МБ |
| Файлы | чтение и запись до 10 МБ; список до 5 000 записей; до 20 наблюдателей |
| Агенты | промпт до 20 000 символов, 6 в минуту на карточку (метод и порт вместе), до 10 в очереди на агента; команда до 20 000 символов; 30 команд в минуту на карточку (run и порт терминала вместе, тайм-аут до 120 с), write 60 в минуту; экран до 500 строк; вывод доставляется каждые 100 мс или 64 КБ |
| Инструменты | результат до 1 МБ; тайм-аут 30 с (максимум 120 с); прогресс 4 раза в секунду |
| Порты | 20 сообщений/с на выход; сохраняемое значение до 256 КБ; тайм-аут запроса 30 с (максимум 120 с) |
| Интерфейс карточки | заголовок до 120 (30 в минуту); статус до 80, статус/бейдж/обзор — по 120 в минуту; строки обзора до 160; тост до 280 (один в 2 с); текст подтверждения до 1 000 (10 в минуту); до 12 пунктов меню (30 изменений в минуту); settings.set 60 в минуту; tools.setEnabled 30 в минуту; usage.summary 6 в минуту; внимание раз в 10 с; полёт камеры раз в 5 с; изменение размера раз в 500 мс; до 4 созданных карточек; буфер обмена раз в секунду, до 1 МБ |
| Журнал | строка до 2 000 символов; 50 строк в секунду |
| Страницы | во всём приложении работает до 24 страниц карточек; из них в фоне — до 8; усыпление через 60 с скрытности, на сохранение — 1 с; пульс каждые 5 с, «не отвечает» через 15 с; готовность — в течение 10 с после запуска |