Adopting a uniform return convention is most effective when it is applied consistently. A single function that raises instead of returning, or that skipsDocumentation 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.
msg on success, creates a gap that erodes the pattern’s value. The practices below help teams establish a codebase-wide standard that makes every function predictable — whether you are reading it for the first time or debugging it at 2 AM.
Always initialize the response at the top
Always initialize the response at the top
Declare Avoid initializing the response inside an
response = DataAndMsgReturn() (or response = BasicReturn()) as the very first line of the function body, before any logic, guards, or branching. This ensures there is always a valid return value no matter how control flow exits the function, and it makes the intended return type immediately visible to anyone reading the code.if branch or late in the function body — it makes it easy to accidentally return an uninitialized value on some code paths.Use BasicReturn for void-style operations
Use BasicReturn for void-style operations
If a function performs an action but has no meaningful payload to return — writing a file, deleting a record, sending a notification — use Returning a
BasicReturn rather than DataAndMsgReturn. This keeps the function signature honest: it tells callers up front that there is no data to inspect, only a success or failure signal.DataAndMsgReturn with an empty data field from a write-only function is not wrong, but it misleads readers into expecting a payload that never arrives. Match the class to the intent.Set msg on both success and failure
Set msg on both success and failure
The When
msg field is not only for error messages. Setting a clear, descriptive message on the success path — "User created successfully", "Config loaded and validated" — makes logs and debug output meaningful without any extra tooling. A function that only sets msg on failure gives you half the picture.msg is consistently populated, str(result) and structured logging give you useful audit trails at no extra cost.Never raise in a return-typed function
Never raise in a return-typed function
A function that declares If a caller receives a
-> DataAndMsgReturn or -> BasicReturn as its return type has made a contract: it will always return that type, and it will never raise. Wrap the entire function body in try/except Exception and set ok = False if anything goes wrong.DataAndMsgReturn, they should never need a try/except around the call — they rely on result.ok instead.Propagate errors — don't swallow them
Propagate errors — don't swallow them
When chaining operations, always forward the original exception object from the inner result to the outer one. Do not replace Swallowing the original error makes post-mortem debugging significantly harder, especially across service boundaries or in production logs.
result.error with a plain string, and do not discard it by creating a fresh exception. The original exception carries the full traceback, the original message, and any metadata attached by the inner function.Use to_dict() at the boundary
Use to_dict() at the boundary
Call Serializing early loses attribute access (
to_dict() only at the outermost layer of your application — an API route handler, a CLI output formatter, a message queue publisher. Deep inside business logic, pass DataAndMsgReturn or BasicReturn objects directly, keeping the Pydantic model intact and all fields accessible as attributes.result.data, result.msg) and prevents chaining — keep the model as a model until you need a dictionary.Type-annotate all return types
Type-annotate all return types
Always declare In a team setting, annotated return types act as living documentation — they communicate intent to every developer who reads or calls the function.
-> DataAndMsgReturn or -> BasicReturn in your function signatures. Type annotations make the intended contract visible at a glance, enable IDE auto-completion for .ok, .data, .error, and .msg, and allow MyPy to catch mismatches before they reach production.BasicReturns is fully compatible with MyPy. Because
BasicReturn and DataAndMsgReturn are Pydantic BaseModel subclasses with typed fields, annotating your functions and running mypy will catch type mismatches — such as returning a raw dict from a -> DataAndMsgReturn function, or accessing .data on a BasicReturn — before they reach your test suite or production environment.