refactor(catalog) : address Matthieu review on composables (constant + shared helpers)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m18s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m0s

- useCategoriesAdmin : extract `HYDRA_NO_PAGINATION = 999` to a named
  constant (was duplicated between fetchAll and fetchTypes) + comment
  the post-M0 server-pagination debt.

- useCategoryForm + useApi + shared/utils/api : drop the local copy of
  `extractErrorMessage` in useCategoryForm (it was duplicating the one
  in useApi), and centralize Hydra error / violation extraction in
  `shared/utils/api.ts` via two new helpers :
    - extractApiErrorMessage(data) : tries hydra:description, detail,
      description, message, error, title, hydra:title — used by both
      useApi.onResponseError and useCategoryForm.handleApiError.
    - extractApiViolations(data) : returns the ApiPlatform 422
      violations as a typed array (handles `violations` and
      `hydra:violations`), letting each caller map them onto its own
      fields. useCategoryForm now uses this helper instead of an
      inline loop, ready for the next form drawer to reuse.

handleApiError keeps a manual fallback toast on non-409/422 errors :
the native useApi toast is disabled by design (`toast: false`) to allow
fine-grained 409/422 mapping, so the catch-all branch must re-emit one
or a 500 would be silent.

No behavior change — 43/43 Vitest tests still pass.
This commit is contained in:
2026-05-29 10:46:24 +02:00
parent 27ea881738
commit 62e1b019a1
4 changed files with 98 additions and 69 deletions
+3 -18
View File
@@ -1,5 +1,6 @@
import type { FetchOptions , FetchError } from 'ofetch'
import { $fetch } from 'ofetch'
import { extractApiErrorMessage } from '~/shared/utils/api'
export type AnyObject = Record<string, unknown>
@@ -41,24 +42,8 @@ export function useApi(): ApiClient {
function extractErrorMessage(error: unknown, responseData?: unknown): string {
const data = responseData ?? (error as FetchError)?.data
if (typeof data === 'string') {
return data
}
if (data && typeof data === 'object') {
const record = data as Record<string, unknown>
return (
(record['hydra:description'] as string) ||
(record.detail as string) ||
(record.message as string) ||
(record.error as string) ||
(record.title as string) ||
(record['hydra:title'] as string) ||
''
)
}
const msg = extractApiErrorMessage(data)
if (msg) return msg
return (error as FetchError)?.message ?? 'Erreur inconnue.'
}