- error::ApiError (ResponseError): status + stable snake_case code +
display-safe message + optional details. From<anyhow>/From<diesel> and
into_http_internal_err become a 500 "internal" whose cause is logged,
never sent.
- JSON body, query and path parse failures, the Claims 401 and unknown
routes now answer in the format instead of actix's plain text.
- tags handlers return ApiResult with codes (invalid_tag_name,
tag_not_found, tag_name_taken, no_files, too_many_files,
nothing_to_change, tag_added_and_removed). The rename 409 keeps
existing_tag at the top level for older clients.
- Enhance's error_response builds through ApiError; its codes are
unchanged, and an internal error no longer sends its message.
- duplicates: eight 500s sent format!("{:?}", e) to the client.
Refs #202
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>