BasicReturns is most valuable when every function in a codebase follows the same conventions — not just using the same return types, but populating fields in the same way and checking them in the same order. The practices below capture the patterns that appear throughout the BasicReturns documentation and README, distilled into concrete rules you can apply immediately.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/dev2forge/BasicReturns/llms.txt
Use this file to discover all available pages before exploring further.
Always check ok before accessing data
DataAndMsgReturn.data defaults to None, even on a successful return, if the function did not explicitly set it. Accessing result.data without first verifying result.ok can silently produce None in places where you expect a value.Set msg on both success and failure paths
A descriptive
msg on both paths makes logs and debugging output immediately useful without having to inspect raw exception objects. Treat msg as the human-readable summary of what happened — always set it before returning.Set error explicitly on failure
When
ok is False, always assign an exception or descriptive value to error. Leaving error = None while ok = False forces callers to rely solely on msg for diagnosis, discards the original exception and its stack trace, and breaks any tooling that inspects error for structured reporting.Use BasicReturn for write/action operations, DataAndMsgReturn for read/query operations
Choose the return type that matches the function’s purpose. If the caller needs a result value, use
DataAndMsgReturn. If the function only performs a side effect and the caller only needs to know whether it succeeded, BasicReturn is sufficient and signals that intent to the reader.Consistent error handling
Validate inputs at the top of the function and return early with a fully populated failure result before doing any real work. This keeps the main logic free of nested conditionals and makes the validation rules easy to read and test in isolation. The following example is taken directly from the BasicReturns README:
Serialise with to_dict() for APIs and logging
Both Note that
BasicReturn and DataAndMsgReturn provide a to_dict() method that returns a plain dictionary. Use it when forwarding a result to an HTTP response, a message queue, or a structured log entry — anywhere that expects a serialisable mapping rather than a Pydantic model.DataAndMsgReturn.to_dict() returns an empty dict {} for data when data is None or falsy, so downstream consumers always receive a consistent type for that field.Common Mistakes
Accessing data without checking ok
Accessing data without checking ok
The bug: Accessing The fix: Always gate access to
result.data directly assumes the operation succeeded. If it did not, data is None and any subsequent attribute access or iteration will raise an unexpected error — far from the point where the real failure occurred.data behind an ok check. Handle the failure path explicitly so errors surface with meaningful context.Forgetting to set error when ok=False
Forgetting to set error when ok=False
The bug: Setting The fix: Always assign an exception (or at minimum a descriptive value) to
ok = False without assigning error leaves callers with no structured information about what went wrong. msg alone is a string and cannot be caught, compared programmatically, or logged with a stack trace.error whenever ok is False. This preserves the original exception for callers that need to re-raise, log, or inspect it.Using raw exceptions instead of BasicReturns
Using raw exceptions instead of BasicReturns
When raising is fine: Inside a single function or a tightly scoped module where the exception will be caught immediately in the same call frame, a plain When to prefer BasicReturns: Use
raise is idiomatic Python and perfectly readable.BasicReturn or DataAndMsgReturn at the boundaries of your application — I/O operations, network calls, external service integrations, and any function whose result will be checked by multiple callers in different parts of the codebase. These are the places where a uniform ok/error contract eliminates the need for every call site to know which exceptions to catch.