prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  `mkdocs serve` doesn't recover from build errors
  For example, add a new page to the `pages` setting before you create the file, you then need to manually restart the serve command.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `mkdocs/serve.py`
  Content:
  ```
  1 # coding: utf-8
  2 from __future__ import print_function
  3 
  4 from watchdog import events
  5 from watchdog.observers.polling import PollingObserver
  6 from mkdocs.build import build
  7 from mkdocs.compat import httpserver, socketserver, urlunquote
  8 from mkdocs.config import load_config
  9 import os
  10 import posixpath
  11 import shutil
  12 import sys
  13 import tempfile
  14 
  15 
  16 class BuildEventHandler(events.FileSystemEventHandler):
  17     """
  18     Perform a rebuild when anything in the theme or docs directory changes.
  19     """
  20     def __init__(self, options):
  21         super(BuildEventHandler, self).__init__()
  22         self.options = options
  23 
  24     def on_any_event(self, event):
  25         if not isinstance(event, events.DirModifiedEvent):
  26             print('Rebuilding documentation...', end='')
  27             config = load_config(options=self.options)
  28             build(config, live_server=True)
  29             print(' done')
  30 
  31 
  32 class ConfigEventHandler(BuildEventHandler):
  33     """
  34     Perform a rebuild when the config file changes.
  35     """
  36     def on_any_event(self, event):
  37         if os.path.basename(event.src_path) == 'mkdocs.yml':
  38             super(ConfigEventHandler, self).on_any_event(event)
  39 
  40 
  41 class FixedDirectoryHandler(httpserver.SimpleHTTPRequestHandler):
  42     """
  43     Override the default implementation to allow us to specify the served
  44     directory, instead of being hardwired to the current working directory.
  45     """
  46     base_dir = os.getcwd()
  47 
  48     def translate_path(self, path):
  49         # abandon query parameters
  50         path = path.split('?', 1)[0]
  51         path = path.split('#', 1)[0]
  52         path = posixpath.normpath(urlunquote(path))
  53         words = path.split('/')
  54         words = filter(None, words)
  55         path = self.base_dir
  56         for word in words:
  57             drive, word = os.path.splitdrive(word)
  58             head, word = os.path.split(word)
  59             if word in (os.curdir, os.pardir):
  60                 continue
  61             path = os.path.join(path, word)
  62         return path
  63 
  64     def log_message(self, format, *args):
  65         date_str = self.log_date_time_string()
  66         sys.stderr.write('[%s] %s\n' % (date_str, format % args))
  67 
  68 
  69 def serve(config, options=None):
  70     """
  71     Start the devserver, and rebuild the docs whenever any changes take effect.
  72     """
  73     # Create a temporary build directory, and set some options to serve it
  74     tempdir = tempfile.mkdtemp()
  75     options['site_dir'] = tempdir
  76 
  77     # Only use user-friendly URLs when running the live server
  78     options['use_directory_urls'] = True
  79 
  80     # Perform the initial build
  81     config = load_config(options=options)
  82     build(config, live_server=True)
  83 
  84     # Note: We pass any command-line options through so that we
  85     #       can re-apply them if the config file is reloaded.
  86     event_handler = BuildEventHandler(options)
  87     config_event_handler = ConfigEventHandler(options)
  88 
  89     # We could have used `Observer()`, which can be faster, but
  90     # `PollingObserver()` works more universally.
  91     observer = PollingObserver()
  92     observer.schedule(event_handler, config['docs_dir'], recursive=True)
  93     for theme_dir in config['theme_dir']:
  94         observer.schedule(event_handler, theme_dir, recursive=True)
  95     observer.schedule(config_event_handler, '.')
  96     observer.start()
  97 
  98     class TCPServer(socketserver.TCPServer):
  99         allow_reuse_address = True
  100 
  101     class DocsDirectoryHandler(FixedDirectoryHandler):
  102         base_dir = config['site_dir']
  103 
  104     host, port = config['dev_addr'].split(':', 1)
  105     server = TCPServer((host, int(port)), DocsDirectoryHandler)
  106 
  107     print('Running at: http://%s:%s/' % (host, port))
  108     print('Live reload enabled.')
  109     print('Hold ctrl+c to quit.')
  110     try:
  111         server.serve_forever()
  112     except KeyboardInterrupt:
  113         print('Stopping server...')
  114 
  115     # Clean up
  116     observer.stop()
  117     observer.join()
  118     shutil.rmtree(tempdir)
  119     print('Quit complete')
  120
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/mkdocs/serve.py b/mkdocs/serve.py
  --- a/mkdocs/serve.py
  +++ b/mkdocs/serve.py
  @@ -34,8 +34,11 @@
       Perform a rebuild when the config file changes.
       """
       def on_any_event(self, event):
  -        if os.path.basename(event.src_path) == 'mkdocs.yml':
  -            super(ConfigEventHandler, self).on_any_event(event)
  +        try:
  +            if os.path.basename(event.src_path) == 'mkdocs.yml':
  +                super(ConfigEventHandler, self).on_any_event(event)
  +        except Exception as e:
  +            print(e)
   
   
   class FixedDirectoryHandler(httpserver.SimpleHTTPRequestHandler):
  
verification_info: {"golden_diff": "diff --git a/mkdocs/serve.py b/mkdocs/serve.py\n--- a/mkdocs/serve.py\n+++ b/mkdocs/serve.py\n@@ -34,8 +34,11 @@\n     Perform a rebuild when the config file changes.\n     \"\"\"\n     def on_any_event(self, event):\n-        if os.path.basename(event.src_path) == 'mkdocs.yml':\n-            super(ConfigEventHandler, self).on_any_event(event)\n+        try:\n+            if os.path.basename(event.src_path) == 'mkdocs.yml':\n+                super(ConfigEventHandler, self).on_any_event(event)\n+        except Exception as e:\n+            print(e)\n \n \n class FixedDirectoryHandler(httpserver.SimpleHTTPRequestHandler):\n", "issue": "`mkdocs serve` doesn't recover from build errors\nFor example, add a new page to the `pages` setting before you create the file, you then need to manually restart the serve command.\n\n", "before_files": [{"content": "# coding: utf-8\nfrom __future__ import print_function\n\nfrom watchdog import events\nfrom watchdog.observers.polling import PollingObserver\nfrom mkdocs.build import build\nfrom mkdocs.compat import httpserver, socketserver, urlunquote\nfrom mkdocs.config import load_config\nimport os\nimport posixpath\nimport shutil\nimport sys\nimport tempfile\n\n\nclass BuildEventHandler(events.FileSystemEventHandler):\n    \"\"\"\n    Perform a rebuild when anything in the theme or docs directory changes.\n    \"\"\"\n    def __init__(self, options):\n        super(BuildEventHandler, self).__init__()\n        self.options = options\n\n    def on_any_event(self, event):\n        if not isinstance(event, events.DirModifiedEvent):\n            print('Rebuilding documentation...', end='')\n            config = load_config(options=self.options)\n            build(config, live_server=True)\n            print(' done')\n\n\nclass ConfigEventHandler(BuildEventHandler):\n    \"\"\"\n    Perform a rebuild when the config file changes.\n    \"\"\"\n    def on_any_event(self, event):\n        if os.path.basename(event.src_path) == 'mkdocs.yml':\n            super(ConfigEventHandler, self).on_any_event(event)\n\n\nclass FixedDirectoryHandler(httpserver.SimpleHTTPRequestHandler):\n    \"\"\"\n    Override the default implementation to allow us to specify the served\n    directory, instead of being hardwired to the current working directory.\n    \"\"\"\n    base_dir = os.getcwd()\n\n    def translate_path(self, path):\n        # abandon query parameters\n        path = path.split('?', 1)[0]\n        path = path.split('#', 1)[0]\n        path = posixpath.normpath(urlunquote(path))\n        words = path.split('/')\n        words = filter(None, words)\n        path = self.base_dir\n        for word in words:\n            drive, word = os.path.splitdrive(word)\n            head, word = os.path.split(word)\n            if word in (os.curdir, os.pardir):\n                continue\n            path = os.path.join(path, word)\n        return path\n\n    def log_message(self, format, *args):\n        date_str = self.log_date_time_string()\n        sys.stderr.write('[%s] %s\\n' % (date_str, format % args))\n\n\ndef serve(config, options=None):\n    \"\"\"\n    Start the devserver, and rebuild the docs whenever any changes take effect.\n    \"\"\"\n    # Create a temporary build directory, and set some options to serve it\n    tempdir = tempfile.mkdtemp()\n    options['site_dir'] = tempdir\n\n    # Only use user-friendly URLs when running the live server\n    options['use_directory_urls'] = True\n\n    # Perform the initial build\n    config = load_config(options=options)\n    build(config, live_server=True)\n\n    # Note: We pass any command-line options through so that we\n    #       can re-apply them if the config file is reloaded.\n    event_handler = BuildEventHandler(options)\n    config_event_handler = ConfigEventHandler(options)\n\n    # We could have used `Observer()`, which can be faster, but\n    # `PollingObserver()` works more universally.\n    observer = PollingObserver()\n    observer.schedule(event_handler, config['docs_dir'], recursive=True)\n    for theme_dir in config['theme_dir']:\n        observer.schedule(event_handler, theme_dir, recursive=True)\n    observer.schedule(config_event_handler, '.')\n    observer.start()\n\n    class TCPServer(socketserver.TCPServer):\n        allow_reuse_address = True\n\n    class DocsDirectoryHandler(FixedDirectoryHandler):\n        base_dir = config['site_dir']\n\n    host, port = config['dev_addr'].split(':', 1)\n    server = TCPServer((host, int(port)), DocsDirectoryHandler)\n\n    print('Running at: http://%s:%s/' % (host, port))\n    print('Live reload enabled.')\n    print('Hold ctrl+c to quit.')\n    try:\n        server.serve_forever()\n    except KeyboardInterrupt:\n        print('Stopping server...')\n\n    # Clean up\n    observer.stop()\n    observer.join()\n    shutil.rmtree(tempdir)\n    print('Quit complete')\n", "path": "mkdocs/serve.py"}], "after_files": [{"content": "# coding: utf-8\nfrom __future__ import print_function\n\nfrom watchdog import events\nfrom watchdog.observers.polling import PollingObserver\nfrom mkdocs.build import build\nfrom mkdocs.compat import httpserver, socketserver, urlunquote\nfrom mkdocs.config import load_config\nimport os\nimport posixpath\nimport shutil\nimport sys\nimport tempfile\n\n\nclass BuildEventHandler(events.FileSystemEventHandler):\n    \"\"\"\n    Perform a rebuild when anything in the theme or docs directory changes.\n    \"\"\"\n    def __init__(self, options):\n        super(BuildEventHandler, self).__init__()\n        self.options = options\n\n    def on_any_event(self, event):\n        if not isinstance(event, events.DirModifiedEvent):\n            print('Rebuilding documentation...', end='')\n            config = load_config(options=self.options)\n            build(config, live_server=True)\n            print(' done')\n\n\nclass ConfigEventHandler(BuildEventHandler):\n    \"\"\"\n    Perform a rebuild when the config file changes.\n    \"\"\"\n    def on_any_event(self, event):\n        try:\n            if os.path.basename(event.src_path) == 'mkdocs.yml':\n                super(ConfigEventHandler, self).on_any_event(event)\n        except Exception as e:\n            print(e)\n\n\nclass FixedDirectoryHandler(httpserver.SimpleHTTPRequestHandler):\n    \"\"\"\n    Override the default implementation to allow us to specify the served\n    directory, instead of being hardwired to the current working directory.\n    \"\"\"\n    base_dir = os.getcwd()\n\n    def translate_path(self, path):\n        # abandon query parameters\n        path = path.split('?', 1)[0]\n        path = path.split('#', 1)[0]\n        path = posixpath.normpath(urlunquote(path))\n        words = path.split('/')\n        words = filter(None, words)\n        path = self.base_dir\n        for word in words:\n            drive, word = os.path.splitdrive(word)\n            head, word = os.path.split(word)\n            if word in (os.curdir, os.pardir):\n                continue\n            path = os.path.join(path, word)\n        return path\n\n    def log_message(self, format, *args):\n        date_str = self.log_date_time_string()\n        sys.stderr.write('[%s] %s\\n' % (date_str, format % args))\n\n\ndef serve(config, options=None):\n    \"\"\"\n    Start the devserver, and rebuild the docs whenever any changes take effect.\n    \"\"\"\n    # Create a temporary build directory, and set some options to serve it\n    tempdir = tempfile.mkdtemp()\n    options['site_dir'] = tempdir\n\n    # Only use user-friendly URLs when running the live server\n    options['use_directory_urls'] = True\n\n    # Perform the initial build\n    config = load_config(options=options)\n    build(config, live_server=True)\n\n    # Note: We pass any command-line options through so that we\n    #       can re-apply them if the config file is reloaded.\n    event_handler = BuildEventHandler(options)\n    config_event_handler = ConfigEventHandler(options)\n\n    # We could have used `Observer()`, which can be faster, but\n    # `PollingObserver()` works more universally.\n    observer = PollingObserver()\n    observer.schedule(event_handler, config['docs_dir'], recursive=True)\n    for theme_dir in config['theme_dir']:\n        observer.schedule(event_handler, theme_dir, recursive=True)\n    observer.schedule(config_event_handler, '.')\n    observer.start()\n\n    class TCPServer(socketserver.TCPServer):\n        allow_reuse_address = True\n\n    class DocsDirectoryHandler(FixedDirectoryHandler):\n        base_dir = config['site_dir']\n\n    host, port = config['dev_addr'].split(':', 1)\n    server = TCPServer((host, int(port)), DocsDirectoryHandler)\n\n    print('Running at: http://%s:%s/' % (host, port))\n    print('Live reload enabled.')\n    print('Hold ctrl+c to quit.')\n    try:\n        server.serve_forever()\n    except KeyboardInterrupt:\n        print('Stopping server...')\n\n    # Clean up\n    observer.stop()\n    observer.join()\n    shutil.rmtree(tempdir)\n    print('Quit complete')\n", "path": "mkdocs/serve.py"}]}