Main coves client

fix(errors): show the server's message for plain 4xx errors master

A plain 4xx ApiException (a rate limit, a ban, a validation-style rejection) always showed the generic fallback, so users never saw why the server said no. getErrorMessage now shows the server's trimmed message for any 4xx other than 401 and 404, and keeps the fallback when that message is blank, is only the machine error code, is the "Request failed with status N" diagnostic, looks like HTML, spans lines, or is longer than 200 characters. The community join button went through none of this: it showed raw exception text. It now uses ErrorMessage.subscription, and a leave that 404s (the subscription isn't indexed yet, or was removed elsewhere) shows "Could not update subscription. Please try again." instead of "Content not found", which also fixes the community feed header. Changes: - error_messages.dart: 4xx server-message passthrough with the fallback rules above; ErrorMessage.subscription maps NotFoundException to the subscription fallback - api_exceptions.dart: requestFailedMessageForStatus names the no-message diagnostic so the helper can recognise it - community_join_button.dart: both catch branches use ErrorMessage.subscription; the ScaffoldMessenger is captured before the await so a failure still shows when a lazy list disposes the button - Provider tests pin that providers rethrow the service's exact exception - Maestro b8 flow: a rate-limited vote shows the server's message - Tests: error_messages_test, community_join_button_test (join, leave 404, unmount mid-request), post_card_test Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>