# Error Handling and Resilience

## Overview

This codebase handles error conditions primarily through Spring MVC validation and form re-display rather than exception-driven recovery. The goal is to prevent invalid state from being persisted, surface field-level feedback to users, and keep the request flow predictable when input does not meet domain rules.

In practice, the `owner` package focuses on validation errors during pet creation and update. The controller tests show that invalid submissions are returned to the same form view with errors attached to the model, while successful submissions are redirected. The validator tests show that domain validation rules are enforced at the `Pet` level, using Spring's `Errors` abstraction to record violations.

## Implementation Patterns

### 1. Validate before accepting state changes

The validator is the first line of defense. `PetValidator` is exercised in [`PetValidatorTests`](../../src/test/java/org/springframework/samples/petclinic/owner/PetValidatorTests.java), which confirm that invalid data produces field errors for name, type, and birth date.

This is a standard Spring validation pattern:
- inspect the submitted object
- reject invalid fields through `Errors`
- let the web layer decide how to render the response

### 2. Re-render forms when validation fails

[`PetControllerTests`](../../src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java) show the controller behavior for invalid submissions:
- blank names return the same form
- duplicate names return the same form
- missing pet type returns the same form
- invalid birth dates return the same form

The response includes model errors such as:
- `required`
- `duplicate`
- `typeMismatch`
- `typeMismatch.birthDate`

This keeps the interaction resilient: bad input does not crash the request or create partial updates.

### 3. Separate success flow from error flow

The controller tests also show a clear success path. Valid create and update requests redirect to the owner detail page. This split is important because it ensures that only validated objects leave the form-handling layer.

### 4. Use field-level errors instead of generic failure states

The error model is specific to the field that failed validation. That lets the UI point users to the exact problem rather than showing an opaque failure message. The tests assert this pattern directly with field-specific error codes.

## Key Classes

### [`PetValidator`](../../src/test/java/org/springframework/samples/petclinic/owner/PetValidatorTests.java)

The validator encapsulates domain-level checks for `Pet`. Its responsibility is to reject incomplete or invalid input before it reaches persistence or downstream workflows.

Why it matters:
- centralizes validation logic
- keeps controllers thin
- makes validation rules testable in isolation

### [`ValidateHasErrors`](../../src/test/java/org/springframework/samples/petclinic/owner/PetValidatorTests.java)

This nested test class documents the expected failure modes of validation. It shows that the validator should report errors for:
- missing or blank pet names
- missing pet types
- missing birth dates

This is important because the resilience strategy here depends on predictable, structured failures.

### [`ProcessCreationFormHasErrors`](../../src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java)

This nested test class describes how creation requests behave when validation fails. Instead of proceeding, the controller returns the pet form and preserves error state.

Why it matters:
- prevents invalid pets from being created
- preserves the user’s context
- keeps the flow recoverable without page-level exceptions

### [`ProcessUpdateFormHasErrors`](../../src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java)

This nested test class covers the same resilience pattern for updates. Update requests are treated as equally sensitive to invalid input, and errors are routed back to the same edit form.

Why it matters:
- update flows are protected the same way as create flows
- users can correct mistakes without losing context
- the system avoids partial or inconsistent updates

## How It Fits Together

```mermaid
flowchart TD
A["Controller form submission"] --> B["Spring binding and validation"]
B --> C["PetValidator checks domain fields"]
C --> D["BindingResult collects field errors"]
D --> E["Controller returns createOrUpdate form"]
D --> F["Controller redirects to owner detail"]
```

The flow is intentionally simple:

1. A user submits the pet form.
2. Spring binds request parameters into the domain object.
3. `PetValidator` checks required business fields.
4. Validation failures are captured in `BindingResult` / `Errors`.
5. If errors exist, the controller re-renders the form with those errors.
6. If validation passes, the controller redirects to the owner page.

This is the main resilience mechanism in this area of the codebase: validation failures are recoverable, visible, and localized.

## Notes for Developers

- Keep domain rules in validators where possible. That makes them reusable across create and update flows.
- Prefer field-level validation errors over broad exception handling for expected input problems.
- Preserve the form view on validation failure so users can correct input without losing context.
- Add tests for both the success path and each error branch. The existing controller and validator tests are the documentation of expected behavior.
- When introducing new form fields, update both the validator and the controller tests so the error contract stays explicit.
- If you add truly exceptional conditions, handle them separately from validation so user input errors do not become system failures.
