Changelog for monad-rail-0.1.0.0
Revision history for monad-rail
0.1.0.0 -- 2026-03-18
- First release.
RailT monad transformer for Railway-Oriented Programming.
Rail type alias for RailT Failure IO.
throwError for single-error failures. Accepts any error type with HasErrorInfo, Show, and Typeable constraints — wraps it in SomeError automatically.
<!> operator for parallel validation with error accumulation.
HasErrorInfo typeclass for custom error types. Only errorPublicMessage :: e -> Text is required. All other methods have defaults:
errorCode :: e -> Text — defaults to the constructor name via Data.toConstr (requires Data).
errorDetails :: e -> Maybe SomeErrorDetails — defaults to Nothing. Uses the existential SomeErrorDetails wrapper (see below).
errorSeverity :: e -> ErrorSeverity — defaults to Error.
errorInternalMessage, errorException, errorCallStack — all default to Nothing.
publicErrorInfo :: HasErrorInfo e => e -> PublicErrorInfo — assembles the user-facing error record from an instance.
internalErrorInfo :: HasErrorInfo e => e -> InternalErrorInfo — assembles the internal diagnostic record from an instance.
SomeErrorDetails existential wrapper — holds any value with ToJSON, Show, and Typeable constraints. Preserves the original type at runtime, allowing recovery via Data.Typeable.cast while supporting JSON serialization. Used by errorDetails and PublicErrorInfo.details.
PublicErrorInfo with fields publicMessage, code, and details (where details :: Maybe SomeErrorDetails). Serializes to JSON as message, code, and details. Null fields are omitted from JSON output.
InternalErrorInfo with fields internalMessage, severity, exception, and callStack. Implements ToJSON for structured log output; null fields are omitted. Never included in public API responses.
SomeError existential wrapper — holds any error with HasErrorInfo, Show, and Typeable constraints. The Typeable constraint allows recovery of the original error type via Data.Typeable.cast.
ErrorSeverity with Error and Critical levels.
UnhandledException data type for wrapping runtime exceptions as Railway errors, with fields unhandledCode, unhandledException, unhandledCallStack, and unhandledMessage. unhandledCode is Maybe Text and defaults to "UnhandledException" when Nothing.
tryRail (with HasCallStack) for lifting IO actions that may throw into the Railway, converting any exception to an UnhandledException error with Critical severity and an automatic call stack.
tryRailWithCode (with HasCallStack) — like tryRail but accepts a function SomeException -> Text as the first argument, allowing the error code to be derived from the caught exception. Pass const "MyCode" for a fixed code, or inspect the exception to return different codes dynamically.
tryRailWithError (with HasCallStack, HasErrorInfo e) — like tryRailWithCode, but takes an error-building function SomeException -> e and uses errorCode and errorPublicMessage from the resulting HasErrorInfo instance as the error code and public message.
throwUnhandledException (with HasCallStack) — convenience function for throwing an UnhandledException with the default code "UnhandledException". Captures the call stack automatically at the call site.
throwUnhandledExceptionWithCode (with HasCallStack) — like throwUnhandledException but accepts a domain-specific error code as the first argument.
runRailT — the general form of runRail for custom base monads. Use when RailT is stacked on top of StateT, ReaderT, or any other transformer.