PhoenixKit.Modules.Publishing.Errors (PhoenixKitPublishing v0.1.5)

Copy Markdown View Source

Central mapping from error atoms (returned by the Publishing module's public API) to translated human-readable strings.

Keeping the API layer locale-agnostic means callers and integration consumers can pattern-match on atoms and decide their own presentation. Anything user-facing (flash messages, error banners) goes through message/1 which wraps each mapping in gettext/1 using the PhoenixKitWeb.Gettext backend.

Supported reason shapes

  • plain atoms — :not_found, :slug_already_exists, :title_required, :invalid_mode, :no_published_version, etc.
  • tagged tuples — {:ai_translation_failed, reason}, {:ai_extract_failed, reason}, {:ai_request_failed, reason}, {:source_post_read_failed, reason}
  • strings — passed through unchanged (legacy / interpolated messages)
  • unknown reasons — rendered as "Unexpected error: <inspect>" via gettext so nothing ever silently surfaces a raw struct

Log-safe error inspection

truncate_for_log/2 is the canonical way to render an opaque error reason inside Logger.* calls that target external HTTP responses or large AI payloads. It coerces the value to a string via inspect/1 and clips it to a fixed character budget so a runaway response body never floods the logs.

Example

iex> PhoenixKit.Modules.Publishing.Errors.message(:not_found)
"Not found"

iex> PhoenixKit.Modules.Publishing.Errors.message({:ai_translation_failed, :timeout})
"AI translation failed: :timeout"

Summary

Types

Atoms returned by Publishing's public API on error.

Tagged-tuple errors that carry a downstream reason.

Functions

Translates an error reason (atom, tagged tuple, or string) into a user-facing string via gettext.

Renders any error reason as a log-safe string clipped to max chars.

Types

error_atom()

@type error_atom() ::
  :already_exists
  | :cache_miss
  | :cannot_delete_live
  | :conflicts_with_post_slug
  | :db_update_failed
  | :destination_exists
  | :group_not_found
  | :invalid_content
  | :invalid_format
  | :invalid_mode
  | :invalid_name
  | :invalid_path
  | :invalid_slug
  | :invalid_status
  | :invalid_type
  | :invalid_version
  | :last_language
  | :last_version
  | :no_post
  | :no_published_version
  | :no_uuid
  | :not_found
  | :not_published
  | :post_not_found
  | :post_trashed
  | :reserved_language_code
  | :reserved_route_word
  | :slug_already_exists
  | :slug_taken
  | :title_required
  | :unpublished
  | :version_access_disabled
  | :ai_disabled
  | :ai_no_prompt
  | :ai_endpoint_not_found
  | :ai_endpoint_disabled

Atoms returned by Publishing's public API on error.

tagged_error()

@type tagged_error() ::
  {:ai_translation_failed, term()}
  | {:ai_extract_failed, term()}
  | {:ai_request_failed, term()}
  | {:source_post_read_failed, term()}

Tagged-tuple errors that carry a downstream reason.

Functions

message(reason)

@spec message(error_atom() | tagged_error() | term()) :: String.t()

Translates an error reason (atom, tagged tuple, or string) into a user-facing string via gettext.

truncate_for_log(reason, max \\ 500)

@spec truncate_for_log(term(), pos_integer()) :: String.t()

Renders any error reason as a log-safe string clipped to max chars.

Use inside Logger.* calls that may include external HTTP response bodies, AI completions, or other unbounded payloads — without the cap a single failed AI request can flood logs with tens of KB.

Returns the inspected form unchanged when it fits, or appends an ellipsis hint when truncated.