aosabook/500lines · error · ServerException
Unknown object '{0}'
Error message
Unknown object '{0}' What it means
Thrown by case_always_fail.act, the terminal handler in the case dispatch chain. case_always_fail.test unconditionally returns True, so its act runs only when every earlier case (case_no_file, case_cgi_file, case_existing_file, and the directory cases) failed to match. It signals that the path exists but is none of the supported object types, raising ServerException("Unknown object '{path}'").
Source
Thrown at web-server/code/05-refactored/server.py:128
handler.handle_error(msg)
def test(self, handler):
return os.path.isdir(handler.full_path) and \
not os.path.isfile(self.index_path(handler))
def act(self, handler):
self.list_dir(handler, handler.full_path)
#-------------------------------------------------------------------------------
class case_always_fail(base_case):
'''Base case if nothing else worked.'''
def test(self, handler):
return True
def act(self, handler):
raise ServerException("Unknown object '{0}'".format(handler.path))
#-------------------------------------------------------------------------------
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
'''
If the requested path maps to a file, that file is served.
If anything goes wrong, an error page is constructed.
'''
Cases = [case_no_file(),
case_cgi_file(),
case_existing_file(),
case_directory_index_file(),
case_directory_no_index_file(),
case_always_fail()]
# How to display an error.
Error_Page = """\View on GitHub (pinned to fba689d101)
Solutions
- Inspect the object type of handler.full_path with os.path.isfile / os.path.isdir / os.path.islink to see which case should have matched.
- Ensure the Cases list includes handlers for every object type you serve (directory index, directory listing, CGI).
- Add a dedicated case before case_always_fail for the unhandled object type.
- If the object should not be served, treat this as expected behaviour and let the error page render.
Example fix
# before: Cases missing a directory-index case, so a real dir hits always_fail
Cases = [case_no_file(), case_cgi_file(), case_existing_file(), case_always_fail()]
# after: insert the directory cases before the catch-all
Cases = [case_no_file(),
case_cgi_file(),
case_existing_file(),
case_directory_index_file(),
case_directory_no_index_file(),
case_always_fail()] Defensive patterns
Strategy: validation
Validate before calling
# classify the object before relying on the case chain
import os
p = handler.full_path
kind = ('dir' if os.path.isdir(p) else
'file' if os.path.isfile(p) else
'special')
if kind == 'special':
# add a case or reject explicitly before case_always_fail
return None Try / catch
try:
for case in Cases:
if case.test(handler):
case.act(handler)
break
except ServerException:
# render the generic error page
handler.error_page() Prevention
- Order Cases from most specific to least, always ending with case_always_fail.
- Register a case class for every filesystem object type you intend to serve.
- Reject special files (sockets, devices) explicitly with an early case.
- Unit-test the chain against a file, a directory with/without index, and a missing path.
When it happens
Trigger: handler.full_path exists but is not a regular file, not a CGI script, and not a servable directory (e.g. no index file and directory listing disabled/failed). Concretely: a socket, FIFO, device node, or a directory whose index case was omitted from the Cases list.
Common situations: A new filesystem object type was added but no case class was registered for it; the Cases list was reordered so a directory case is missing; requesting a special file like /dev/null through the server; permission issues that make stat behave oddly.
AI-assisted analysis of aosabook/500lines@fba689d101 (2026-08-13).
Data as JSON: /api/errors/ca3266343f741d9d.
Report an issue: GitHub.