Magnus Persson
Add the Photo studio tab: webcam or upload, five restyling looks, admin switch, consent and input checks
c566758 Download src/errors.py from magnusp/image-lab: direct link, hf CLI and curl.
- Browser
- Download file 2.65 kB
-
https://huggingface.co/spaces/magnusp/image-lab/resolve/main/src/errors.py
- Command line
-
hf download hf://spaces/magnusp/image-lab/src/errors.py
-
curl -L -o errors.py https://huggingface.co/spaces/magnusp/image-lab/resolve/main/src/errors.py
2.65 kB
| """Typed errors. Each maps to a locale key; raw details never reach visitors (spec section 15).""" | |
| from __future__ import annotations | |
| class AppError(Exception): | |
| code = "unexpected" | |
| message_key = "error.generic" | |
| # True only when a failure after the provider call is known not to have been billed. | |
| unbilled = False | |
| class EmptyInputError(AppError): | |
| code = "empty_input" | |
| message_key = "error.empty" | |
| class TooLongInputError(AppError): | |
| code = "too_long" | |
| message_key = "error.too_long" | |
| class ProviderTimeoutError(AppError): | |
| code = "timeout" | |
| message_key = "error.timeout" | |
| class ProviderError(AppError): | |
| """A provider call failed or returned something unusable. Details stay in server logs.""" | |
| code = "provider_error" | |
| message_key = "error.generic" | |
| class MalformedReplyError(ProviderError): | |
| """The provider answered, but not with usable JSON. Worth one retry, unlike a refusal.""" | |
| code = "malformed_reply" | |
| class RateLimitedError(AppError): | |
| code = "rate_limited" | |
| message_key = "error.busy" | |
| unbilled = True | |
| class CooldownError(AppError): | |
| code = "cooldown" | |
| message_key = "error.cooldown" | |
| class BudgetReachedError(AppError): | |
| code = "budget_reached" | |
| unbilled = True | |
| message_key = "error.budget" | |
| class PausedError(AppError): | |
| code = "paused" | |
| message_key = "error.paused" | |
| class SafetyRefusalError(AppError): | |
| message_key = "error.safety" | |
| def __init__(self, code: str = "refused", rewrite: str | None = None) -> None: | |
| super().__init__(code) | |
| self.code = code | |
| self.rewrite = rewrite | |
| class CheckFailedError(AppError): | |
| """A safety check could not run. Generation stops (fail closed).""" | |
| code = "check_failed" | |
| message_key = "error.generic" | |
| class BadImageError(AppError): | |
| """An uploaded photo is not an image we can use (not an image, too big, unreadable).""" | |
| code = "bad_image" | |
| message_key = "photo.bad_image" | |
| unbilled = True | |
| class ConsentRequiredError(AppError): | |
| """The visitor did not confirm that the photo is sent to an external service.""" | |
| code = "consent_required" | |
| message_key = "photo.need_consent" | |
| unbilled = True | |
| class FeatureOffError(AppError): | |
| """The photo studio is switched off (it is switched on from the admin account).""" | |
| code = "feature_off" | |
| message_key = "photo.off" | |
| unbilled = True | |
| def error_code(exc: BaseException) -> str: | |
| return exc.code if isinstance(exc, AppError) else AppError.code | |
| def error_message_key(exc: BaseException) -> str: | |
| return exc.message_key if isinstance(exc, AppError) else AppError.message_key | |