Describe the bug
When an endpoint function forgets to return a value (returns None implicitly), AirResponse renders the literal string "None" as HTML content in the browser instead of raising an error.
In src/air/responses.py line 28:
def render(self, tag: BaseTag | str) -> bytes | memoryview:
return super().render(str(tag))
str(None) produces the string "None", which gets rendered as a 200 OK HTML page.
Steps to reproduce
import air
app = air.Air()
@app.page
def index():
air.H1("Hello, world!")
# forgot to return
Visit http://127.0.0.1:8000/ and see the literal text "None" in the browser.
Expected behavior
A missing return should produce a clear error (e.g., TypeError with "endpoint returned None, did you forget a return statement?") rather than silently rendering "None" as page content.
The previous implementation would raise AttributeError on None (because None.render() fails), which was at least a visible error.
Origin
Introduced by PR #377 which changed AirResponse.render to call str(tag) on any input. Found during #1067 investigation.
Affected versions
0.30.0 to present (0.45.0)
Describe the bug
When an endpoint function forgets to return a value (returns
Noneimplicitly),AirResponserenders the literal string "None" as HTML content in the browser instead of raising an error.In
src/air/responses.pyline 28:str(None)produces the string"None", which gets rendered as a 200 OK HTML page.Steps to reproduce
Visit
http://127.0.0.1:8000/and see the literal text "None" in the browser.Expected behavior
A missing return should produce a clear error (e.g.,
TypeErrorwith "endpoint returned None, did you forget a return statement?") rather than silently rendering "None" as page content.The previous implementation would raise
AttributeErroronNone(becauseNone.render()fails), which was at least a visible error.Origin
Introduced by PR #377 which changed
AirResponse.renderto callstr(tag)on any input. Found during #1067 investigation.Affected versions
0.30.0 to present (0.45.0)