magicFormErrorsEnricher function

String? magicFormErrorsEnricher(
  1. Element element,
  2. RefRegistry refs
)

Enricher: emits magicFormErrors: <field>="<text>",... for elements under a MagicForm whose controller carries server-side ValidatesRequests errors matching the form's own field set.

Cross-form leak guard: the emitted list is the intersection of the controller's validationErrors.keys and the form's fieldNames. A controller with no ValidatesRequests mixin, no errors, or no errors matching the form's fields yields null.

Per-field error text is quoted and truncated to 80 characters; longer messages collapse to their first 77 characters followed by .... Insertion order from validationErrors is preserved.

Implementation

String? magicFormErrorsEnricher(Element element, RefRegistry refs) {
  // 1. Walk ancestors for a MagicForm — same pattern as magicFormEnricher.
  final _MagicFormBinding? binding = _findAncestorMagicFormBinding(element);
  if (binding == null) return null;

  final MagicController? controller = binding.controller;
  if (controller is! ValidatesRequests) return null;

  final Map<String, String> errors = controller.validationErrors;
  if (errors.isEmpty) return null;

  // 2. Intersect with the form's fieldNames when available; otherwise
  //    surface every error key (legacy MagicForm has no fieldNames).
  final Set<String>? scope = binding.fieldNames;
  final Iterable<MapEntry<String, String>> kept = scope == null
      ? errors.entries
      : errors.entries.where((e) => scope.contains(e.key));

  // 3. Emit quoted per-field text. Truncate long messages to 80 chars.
  final List<String> parts = kept
      .map((e) => '${e.key}="${_truncateErrorText(e.value)}"')
      .toList(growable: false);
  if (parts.isEmpty) return null;

  return 'magicFormErrors: ${parts.join(',')}';
}