aosabook/500lines · error · ServerException

Unknown object '{0}'

Error message

Unknown object '{0}'

What it means

Raised by case_always_fail.act in the 04-cgi server, the unconditional last case. After case_cgi_file (.py files), case_existing_file (other files), and case_directory_no_index_file (directories) are tried, anything left — an existing object that is none of those — triggers Unknown object.

Source

Thrown at web-server/code/04-cgi/server.py:82

        return os.path.join(handler.full_path, 'index.html')

    def test(self, handler):
        return os.path.isdir(handler.full_path) and \
               not os.path.isfile(self.index_path(handler))

    def act(self, handler):
        handler.list_dir(handler.full_path)

#-------------------------------------------------------------------------------

class case_always_fail(object):
    '''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

  1. Add a case class earlier in Cases to handle the object type.
  2. Keep only regular files (.py and otherwise) and directories in the served root.
  3. Make the requested path a type an existing case matches.

Example fix

// before
# request a special file -> case_always_fail
// after
# remove the special file, or add a dedicated case handler
Defensive patterns

Strategy: fallback

Validate before calling

# after cgi/file/dir cases, guard remaining object types explicitly
import os
if os.path.exists(handler.full_path) and not os.path.isfile(handler.full_path) and not os.path.isdir(handler.full_path):
    handler.send_error(403, 'Unsupported object')

Try / catch

try:
    for case in self.Cases:
        if case.test(self):
            case.act(self); break
except ServerException:
    self.handle_error(msg)

Prevention

When it happens

Trigger: A request whose full_path exists but is not a .py file, not another regular file, and not a directory, e.g. a device node, socket, or FIFO; or a directory the directory case declined to list.

Common situations: Special files in the served tree; symlinks to unusual targets; an object type no case handles.

Related errors


AI-assisted analysis of aosabook/500lines@fba689d101 (2026-08-13). Data as JSON: /api/errors/5fd2c291b6f1c773. Report an issue: GitHub.