Обробіть відхилену витрату
PHPПомилки, які кажуть, що бюджет, ліміт чи кредити клієнта відхилили запуск, дві форми такої відмови і що робити з кожною.
3 хв читання
Slen перевіряє виклик моделі у флоу за лімітами, які ви задали: за бюджетами проєкту й за кредитами ваших клієнтів. Коли один із них каже «ні», виклик відхиляється до звернення до провайдера. Ця сторінка — про те, як перехопити таку відмову і що з нею робити.
Родина відхиленої витрати
На таку відмову відповідають статусом 402. Обидва SDK кидають такі відмови як одну родину помилок: SpendRefusedException у PHP і SpendRefusedError у Node.js, і кожен код має свій тип, який розширює тип родини. 402 із кодом, для якого SDK не має типу, кидається як сам тип родини.
| Код | HTTP-статус | Тип помилки в SDK | Що це означає | Що робити |
|---|---|---|---|---|
budget_exceeded | 402 | BudgetExceededException PHPBudgetExceededError Node.js | Виклик вивів би бюджет за його ліміт. Те, що бюджет уже тримає й витратив у поточному вікні, разом із холдом, який просить цей виклик, більше за ліміт. | Дочекайтеся наступного вікна бюджету — його resets_at каже коли; бюджет типу total заново не починається. Або підніміть ліміт бюджету. |
operation_limit_exceeded | 402 | OperationLimitExceededException PHPOperationLimitExceededError Node.js | Бюджет на операцію обмежує, скільки може зарезервувати один виклик операції, а холд, який просить цей виклик, вищий за це обмеження. | Просіть менше — менше вихідних токенів, дешевшу модель — або підніміть обмеження. Той самий запит буде відхилено знову, доки одне з них не зміниться. |
concurrency_limit_exceeded | 402 | ConcurrencyLimitException PHPConcurrencyLimitError Node.js | Бюджет типу concurrency — у консолі «Одночасні резерви» — дозволяє тримати відкритими задане число холдів одночасно, і всі вони зайняті викликами, які виконуються. | Надішліть запит знову, коли закінчиться один із викликів, що виконуються, або підніміть ліміт бюджету. Запит до флоу надсилайте знову з новим ключем, бо його відхилене виконання зберігає ключ, який у нього був. Це не ліміт запитів ключа. |
insufficient_credits | 402 | InsufficientCreditsException PHPInsufficientCreditsError Node.js | Рахунок клієнта не може покрити ціну виклику в кредитах, або клієнт не має рахунку цього типу кредитів. Списання або коригування відхиляються так само, коли залишили б баланс нижчим за те, що тримає рахунок. | Поповніть кредити клієнта. Рахунок, у налаштуваннях якого дозволено від’ємний баланс, не відхиляє. |
overrun_stopped | 402 | OverrunStoppedException PHPOverrunStoppedError Node.js | Оцінка виклику моделі у флоу, зроблена знову після того, як узято холд, і до виклику провайдера, перевищила холд більше, ніж дозволяє допуск перевищення вузла, а політика перевитрати вузла моделі — зупинити. Холд повернуто, провайдера не викликано. Той самий код завершує виконання, коли людина відхилила погодження, яке запросила перевитрата, або ніхто не відповів вчасно. У нового вузла моделі політики перевитрати немає, а політика, яка у вузла є, практично не спрацьовує, бо обидві оцінки рахуються за одним і тим самим запитом з різницею в мить. | Надішліть запит знову з новим ключем — виклик буде оцінено заново, і він візьме власний холд. Щоб таких відмов не було, вимкніть політику перевитрати вузла моделі й опублікуйте нову версію. |
overrun_approval_required | 402 | OverrunApprovalRequiredException PHPOverrunApprovalRequiredError Node.js | Оцінка виклику моделі у флоу, зроблена знову після того, як узято холд, і до виклику провайдера, перевищила холд більше, ніж дозволяє допуск перевищення вузла, а політика перевитрати вузла моделі просить людину схвалити різницю. Виконання чекає на це рішення, тому на запит відповідає виконання, що чекає, а не цей код. У нового вузла моделі політики перевитрати немає, а політика, яка у вузла є, практично не спрацьовує, бо обидві оцінки рахуються за одним і тим самим запитом з різницею в мить. | Ухваліть рішення щодо погодження в консолі. Погодження, яке відхилили або щодо якого ніхто не вирішив вчасно, завершує виконання з кодом overrun_stopped. |
Політика, яка відмовляє, до родини не входить. На policy_denied і model_not_allowed відповідають 403 і кидають їх як PolicyDeniedException або PolicyDeniedError — як перевіряється політика, каже стаття Політики. Запит для заблокованого клієнта відхиляється так само, з customer_blocked, як CustomerBlockedException або CustomerBlockedError, які розширюють тип відмови політики.
Два коди родини, overrun_stopped і overrun_approval_required, приходять від політики перевитрати вузла моделі у флоу, а така політика практично не спрацьовує — чому, кажуть їхні рядки в таблиці вище.
Перехопити її
use Slen\Sdk\Exceptions\OperationUncertainException;
use Slen\Sdk\Exceptions\SlenException;
use Slen\Sdk\Exceptions\SpendRefusedException;
use Slen\Sdk\Modules\Operations\Options\ExecuteOptions;
$input = ['messages' => [['role' => 'user', 'content' => 'Write a short follow-up email.']]];
try {
$execution = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: 'order-42:email'));
echo $execution->status->value, PHP_EOL;
} catch (SpendRefusedException $error) {
// The spend was refused, and the code says what refused it.
echo 'refused: ', $error->errorCode, PHP_EOL;
} catch (OperationUncertainException $error) {
// A provider was called and its answer was lost: the call may have been paid for.
echo 'uncertain, request ', $error->requestId, PHP_EOL;
} catch (SlenException $error) {
echo $error->statusCode, ' ', $error->errorCode, ': ', $error->getMessage(), PHP_EOL;
}Код каже, який ліміт відхилив виклик, а таблиця вище — що робити з кожним.
Відхилений виклик нічого не коштував: його провайдер не викликався, і за нього не лишається зарезервованих грошей. У флоу виклики моделей у вузлах до нього оплачено.
Той самий запит відхиляється знову, поки щось не зміниться: бюджет почне наступне вікно, ліміт піднімуть, клієнта поповнять. Виняток —
concurrency_limit_exceeded: він проходить, щойно виклик, що триває, закінчиться.Не надсилайте відхилений запит знову в циклі.
Друга форма: виконання, яке закінчилося відмовою
На запуск відповідають помилкою один раз. Виконання, яке він відкрив, закривається зі статусом rejected і зберігає код. Його cost.estimated — оцінка відхиленого виклику, тобто витрата, якій відмова запобігла, а не витрачені гроші, — або null, коли відмова не назвала оцінки, як для клієнта без кредитів. Той, хто читає його пізніше, отримує виконання, а не помилку: повтор запиту під його ключем, очікування, читання статусу, запуск, надісланий в асинхронному режимі. Тому запуск, який ви надсилаєте знову після відмови, іде під новим ключем.
$again = $slen->operations()->execute('generate_email', $input, new ExecuteOptions(idempotencyKey: 'order-42:email'));
if ($again->isRejected()) {
echo 'rejected: ', $again->errorCode, PHP_EOL;
}Коли вузол моделі має гілку на порті Відмова, відмова не закінчує виконання. Флоу продовжує шлях цією гілкою й вирішує, що почує той, хто викликає.
Вузол Відхилити запит може закінчити виконання з будь-яким кодом, зокрема з кодом цієї родини, і тоді помилка теж не кидається. Код, який реагує на відмову, обробляє обидві форми: catch і статус того, що повернулося.
Де ліміти
Бюджети проєкту — на сторінці Бюджети.
Кредити ваших клієнтів — на сторінці Клієнти, а поповнює їх ваш застосунок через
customers.topUp()— Клієнти та кредити.Політики — на сторінці Політики, у розділі Налаштування.
Що читати далі
Обробка помилок — кожна помилка SDK і чи коштувала вона грошей.
Коди помилок — що означає кожен код і що з ним робити.
Асинхронні запуски й очікування — як прочитати, чим закінчилося виконання.
Зібрано з openapi b070e1f, sdk contract 6a2e0e0, php 4089db3, node 0fa87be