error-model-validation-architect

par kotlin

Concevoir et implémenter un comportement cohérent de validation des API et de gestion des erreurs pour les services Kotlin et Spring. À utiliser lors de la définition des charges utiles d'erreur, du mappage du framework…

npx skills add https://github.com/kotlin/kotlin-backend-agent-skills --skill error-model-validation-architect

Error Model Validation Architect

Source mapping: Tier 2 high-value skill derived from Kotlin_Spring_Developer_Pipeline.md (SK-07).

Mission

Turn ad-hoc exception handling into a deliberate public contract. Treat validation and error mapping as part of API design, not a post-processing afterthought.

Inputs To Read

  • Endpoint contracts and sample payloads.
  • Existing exception classes and error payloads.
  • Validation annotations, custom validators, and business rule failures.
  • Current @ControllerAdvice, security exception handling, and framework defaults.
  • Logging and observability conventions, especially correlation ids and PII policy.

Design The Error Taxonomy

Separate at least these categories:

  • malformed request or unreadable JSON
  • transport-level validation failure
  • not found
  • conflict or concurrency failure
  • business rule rejection
  • authentication and authorization failure
  • downstream dependency failure
  • unexpected internal failure

Do not collapse all non-success outcomes into one generic error envelope.

Status Code Rules

  • Use 400 for malformed input, type mismatch, or invalid transport shape.
  • Use 401 for authentication failure and 403 for authorization failure.
  • Use 404 when the addressed resource is absent.
  • Use 409 for state conflicts, optimistic locking failures, duplicate idempotency keys, and uniqueness races when conflict semantics matter.
  • Use 422 when the payload is structurally valid but violates business rules.
  • Use 429, 502, 503, or 504 deliberately when gateway or dependency behavior is part of the contract.
  • Reserve 500 for genuinely unexpected internal failures.

Advanced Contract Decisions

  • Separate machine-readable error code from human-readable message. Clients should not parse prose.
  • Decide whether field-level validation errors should be aggregated or first-failure only. Make the rule consistent.
  • Preserve nested field paths for complex payloads and collections.
  • Decide whether localization is a server concern, client concern, or documentation-only concern.
  • Standardize correlation or trace identifiers in the error payload only if the platform can produce them consistently.
  • Decide how unknown fields, enum mismatches, and unreadable date formats surface. These are common client-integration pain points.
  • Map downstream failures carefully. Not every remote 500 should become your own 500.
  • If using RFC 7807 Problem Details, decide which extensions are stable parts of the contract and which are internal.

Validation Rules

  • Keep transport validation separate from domain validation even if both ultimately reject the request.
  • Use Kotlin @field: targets for Bean Validation annotations on DTO constructor properties.
  • Prefer dedicated validators or domain rules over abusing regex annotations for business semantics.
  • Validate required configuration or invariants at startup when they are not truly request-scoped.

Framework Exception Coverage

  • Cover MethodArgumentNotValidException, ConstraintViolationException, HttpMessageNotReadableException, MethodArgumentTypeMismatchException, missing-parameter exceptions, and unsupported media-type cases explicitly if the API claims a stable error contract.
  • Decide how security exceptions participate in the shared error model. AuthenticationEntryPoint and AccessDeniedHandler often need explicit alignment with controller advice.
  • Decide how async, scheduled, and messaging failures are reported differently from HTTP failures. One global envelope does not fit every boundary.
  • If the platform uses Problem Details, verify framework-generated problem payloads do not diverge from custom ones during upgrades.

Expert Heuristics

  • Let validation errors help the client recover, but let internal logs help operators diagnose. These are different audiences and should not share the same detail level.
  • If the service is public, keep error-code taxonomy versionable and stable even when internal exception types change.
  • When multiple validation layers reject the same request, choose the most user-actionable signal instead of stacking redundant errors.
  • If a downstream dependency failure is part of the business path, decide whether the contract should expose dependency semantics or normalize them to your own domain.

Output Contract

Return these sections:

  • Error taxonomy: the categories and stable codes.
  • Status mapping: which exception or failure type maps to which status and why.
  • Payload shape: the fields that belong in every error.
  • Framework coverage: which framework exceptions must be handled explicitly.
  • Minimal implementation plan: advice class, exception types, and tests to add.
  • Logging rule: what to log server-side versus what to expose to clients.

Guardrails

  • Do not leak stack traces, SQL fragments, class names, tokens, or secrets to clients.
  • Do not use one generic message for all failures if clients need actionable categories.
  • Do not map every domain failure to 400.
  • Do not let security exceptions bypass the common contract unintentionally.
  • Do not rely on the framework default error shape if the service claims to have a stable API contract.

Quality Bar

A good run of this skill gives clients a predictable error language and gives operators enough server-side detail to debug safely. A bad run produces a pretty error JSON that still conflates malformed input, business rejection, and internal failure.

Plus de skills de kotlin

kotlin-backend-jpa-entity-mapping
kotlin
La classe de données de Kotlin est naturelle pour les DTOs mais dangereuse pour les entités JPA. Hibernate repose sur une sémantique d'identité que la classe de données brise : equals / hashCode sur tous les champs corrompt l'appartenance à Set / Map après des changements d'état, et copy() généré automatiquement crée des doublons détachés d'entités gérées.
kotlin-tooling-agp9-migration
kotlin
Le plugin Android Gradle 9.0 rend les plugins d'application et de bibliothèque Android incompatibles avec le plugin Kotlin Multiplatform dans le même module. Cette compétence vous guide tout au long de la migration.
kotlin-tooling-cocoapods-spm-migration
kotlin
Migrer les projets KMP de CocoaPods (kotlin("native.cocoapods")) vers Swift Package Manager (DSL swiftPMDependencies) — remplace pod() par swiftPackage(),…
kotlin-tooling-immutable-collections-0-5-x-migration
kotlin
Migrer du code Kotlin (et Java) de kotlinx.collections.immutable 0.3.x / 0.4.x vers la dernière version 0.5.x. La branche 0.5.x renomme chaque méthode retournant une copie sur…
kotlin-tooling-java-to-kotlin
kotlin
Convertir des fichiers source Java en Kotlin idiomatique en utilisant une méthodologie de conversion disciplinée en 4 étapes avec 5 invariants vérifiés à chaque étape. Prend en charge la conversion tenant compte du framework, qui gère les cibles de sites d'annotations, les idiomes de bibliothèque et la préservation des API.
kotlin-tooling-native-build-performance
kotlin
Diagnostique et corrige les compilations et liaisons Kotlin/Native lentes dans les projets Kotlin Multiplatform ciblant iOS. À utiliser lorsque l’utilisateur signale des lenteurs sur iOS ou…
kotlin-spring-proxy-compatibility
kotlin
Diagnose and prevent Kotlin plus Spring proxy failures around `@Transactional`, `@Cacheable`, `@Async`, method security, retry, configuration proxies, and JPA…
ci-cd-containerization-advisor
kotlin
Concevoir des pipelines de construction, d'image et de déploiement reproductibles pour les applications Kotlin et Spring, incluant la vérification CI, les conteneurs en couches, la sécurité de déploiement,…