Exceptions

Catch translation failures and configuration errors with the plugin's two typed exception classes.

Both extend Kirby\Exception\Exception and serialize cleanly to API responses. TranslationException fires only when zero units could be translated – partial failures emit a :warning hook instead.

TranslationException

JohannSchopplich\ContentTranslator\Translation\Exception\TranslationException extends Kirby\Exception\Exception. Built-in strategies throw it when zero units survived – per-unit failures keep the source text and only emit a :warning hook.

final class TranslationException extends \Kirby\Exception\Exception
{
    protected static string $defaultKey = 'content-translator.translation';
    protected static int $defaultHttpCode = 502;

    public function __construct(
        string $strategy,
        string $reason,
        int $unitsAttempted,
        int $unitsTranslated = 0,
    );
}

Details Payload

The exception carries structured details for logging:

strategy
String
The strategy identifier (deepl, copilot-ai, or your own).
unitsAttempted
Int
How many units the strategy was asked to translate.
unitsTranslated
Int
How many succeeded before the strategy gave up. Always 0 when this exception is thrown.

For per-unit error context, listen to content-translator.translate:warning – it fires for each failed unit with the underlying Throwable before the strategy decides whether enough units survived.

Catching

use JohannSchopplich\ContentTranslator\Translation\Exception\TranslationException;

try {
    $translator->translateContent('de', 'de', 'en');
} catch (TranslationException $error) {
    $details = $error->getDetails();
    // ['strategy' => 'deepl', 'unitsAttempted' => 12, 'unitsTranslated' => 0]
}

The default HTTP code 502 surfaces when an unhandled TranslationException bubbles up through the Panel.

LogicException

Configuration errors throw Kirby\Exception\LogicException:

TriggerMessage
'strategy' => 'ai' without kirby-copilot installedStrategy "ai" requires the kirby-copilot plugin
'strategy' => 'banana'Unknown strategy "banana"

AuthException

Kirby\Exception\AuthException is thrown for missing API keys:

TriggerMessage
Missing DeepL API keyMissing DeepL API key
Missing Copilot AI provider API keyMissing API key in "johannschopplich.copilot.providers.<name>.apiKey"
For per-unit translation drops, listen to content-translator.translate:warning instead of catching exceptions.