prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve Jupyter workflow when configuration is broken
  ## Description
  > Is your feature request related to a problem? A clear and concise description of what the problem is: "I'm always frustrated when ..."
  
  Using the spaceflights demo on 0.18.1 if I open a `kedro jupyter notebook` session and write `catalog.list()` I will get the following:
  
  ![image](https://user-images.githubusercontent.com/35801847/172139364-e37f8a47-69cf-4749-9ab4-3a9e55ede72e.png)
  
  If I break the `catalog.yml` file so that it is unparsable and run `kedro catalog list` (or any other command like `kedro run` I will get a helpful parse error in the terminal: 
  
  <img width="654" alt="image" src="https://user-images.githubusercontent.com/35801847/172139490-a079095e-52d7-4c80-a8d3-15c5a675239e.png">
  
  However, if I start a `kedro jupyter notebook` session in this state, I get no warning or messaging that Kedro is unable to create the `catalog`, `session` and other global variables. As a user I get this confusing state where the `catalog` is no longer available to me:
  
  <img width="636" alt="image" src="https://user-images.githubusercontent.com/35801847/172139614-8dabbc13-38a4-4785-9afe-bbddf77b974a.png">
  
  
  ## Context
  > Why is this change important to you? How would you use it? How can it benefit other users?
  
  I think novice users can get stuck here with no direction as to why the catalog is not available.
  
  ## Possible Implementation
  
  Surface warning to the jupyter context, perhaps even make a dummy `catalog`, `context`, `session` objects available that expose the log message when called...
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kedro/extras/extensions/ipython.py`
  Content:
  ```
  1 # pylint: disable=import-outside-toplevel,global-statement,invalid-name
  2 """
  3 This script creates an IPython extension to load Kedro-related variables in
  4 local scope.
  5 """
  6 import logging
  7 import sys
  8 from pathlib import Path
  9 from typing import Any, Dict
  10 
  11 from IPython import get_ipython
  12 from IPython.core.magic import needs_local_scope, register_line_magic
  13 
  14 logger = logging.getLogger(__name__)
  15 default_project_path = Path.cwd()
  16 
  17 
  18 def _remove_cached_modules(package_name):
  19     to_remove = [mod for mod in sys.modules if mod.startswith(package_name)]
  20     # `del` is used instead of `reload()` because: If the new version of a module does not
  21     # define a name that was defined by the old version, the old definition remains.
  22     for module in to_remove:
  23         del sys.modules[module]  # pragma: no cover
  24 
  25 
  26 def _find_kedro_project(current_dir: Path):  # pragma: no cover
  27     from kedro.framework.startup import _is_project
  28 
  29     while current_dir != current_dir.parent:
  30         if _is_project(current_dir):
  31             return current_dir
  32         current_dir = current_dir.parent
  33 
  34     return None
  35 
  36 
  37 def reload_kedro(
  38     path: str = None, env: str = None, extra_params: Dict[str, Any] = None
  39 ):
  40     """Line magic which reloads all Kedro default variables.
  41     Setting the path will also make it default for subsequent calls.
  42 
  43 
  44     """
  45     from kedro.framework.cli import load_entry_points
  46     from kedro.framework.project import LOGGING  # noqa # pylint:disable=unused-import
  47     from kedro.framework.project import configure_project, pipelines
  48     from kedro.framework.session import KedroSession
  49     from kedro.framework.startup import bootstrap_project
  50 
  51     # If a path is provided, set it as default for subsequent calls
  52     global default_project_path
  53     if path:
  54         default_project_path = Path(path).expanduser().resolve()
  55         logger.info("Updated path to Kedro project: %s", default_project_path)
  56     else:
  57         logger.info("No path argument was provided. Using: %s", default_project_path)
  58 
  59     metadata = bootstrap_project(default_project_path)
  60     _remove_cached_modules(metadata.package_name)
  61     configure_project(metadata.package_name)
  62 
  63     session = KedroSession.create(
  64         metadata.package_name, default_project_path, env=env, extra_params=extra_params
  65     )
  66     logger.debug("Loading the context from %s", default_project_path)
  67     context = session.load_context()
  68     catalog = context.catalog
  69 
  70     get_ipython().push(
  71         variables={
  72             "context": context,
  73             "catalog": catalog,
  74             "session": session,
  75             "pipelines": pipelines,
  76         }
  77     )
  78 
  79     logger.info("Kedro project %s", str(metadata.project_name))
  80     logger.info(
  81         "Defined global variable 'context', 'session', 'catalog' and 'pipelines'"
  82     )
  83 
  84     for line_magic in load_entry_points("line_magic"):
  85         register_line_magic(needs_local_scope(line_magic))
  86         logger.info("Registered line magic '%s'", line_magic.__name__)  # type: ignore
  87 
  88 
  89 def load_ipython_extension(ipython):
  90     """Main entry point when %load_ext is executed"""
  91 
  92     global default_project_path
  93 
  94     ipython.register_magic_function(reload_kedro, "line", "reload_kedro")
  95 
  96     default_project_path = _find_kedro_project(Path.cwd())
  97 
  98     try:
  99         reload_kedro(default_project_path)
  100     except (ImportError, ModuleNotFoundError):
  101         logger.error("Kedro appears not to be installed in your current environment.")
  102     except Exception:  # pylint: disable=broad-except
  103         logger.warning(
  104             "Kedro extension was registered but couldn't find a Kedro project. "
  105             "Make sure you run '%reload_kedro <project_root>'."
  106         )
  107
  ```
  --- 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/kedro/extras/extensions/ipython.py b/kedro/extras/extensions/ipython.py
  --- a/kedro/extras/extensions/ipython.py
  +++ b/kedro/extras/extensions/ipython.py
  @@ -1,4 +1,4 @@
  -# pylint: disable=import-outside-toplevel,global-statement,invalid-name
  +# pylint: disable=import-outside-toplevel,global-statement,invalid-name,too-many-locals
   """
   This script creates an IPython extension to load Kedro-related variables in
   local scope.
  @@ -8,9 +8,6 @@
   from pathlib import Path
   from typing import Any, Dict
   
  -from IPython import get_ipython
  -from IPython.core.magic import needs_local_scope, register_line_magic
  -
   logger = logging.getLogger(__name__)
   default_project_path = Path.cwd()
   
  @@ -39,9 +36,10 @@
   ):
       """Line magic which reloads all Kedro default variables.
       Setting the path will also make it default for subsequent calls.
  -
  -
       """
  +    from IPython import get_ipython
  +    from IPython.core.magic import needs_local_scope, register_line_magic
  +
       from kedro.framework.cli import load_entry_points
       from kedro.framework.project import LOGGING  # noqa # pylint:disable=unused-import
       from kedro.framework.project import configure_project, pipelines
  @@ -63,7 +61,6 @@
       session = KedroSession.create(
           metadata.package_name, default_project_path, env=env, extra_params=extra_params
       )
  -    logger.debug("Loading the context from %s", default_project_path)
       context = session.load_context()
       catalog = context.catalog
   
  @@ -95,12 +92,11 @@
   
       default_project_path = _find_kedro_project(Path.cwd())
   
  -    try:
  -        reload_kedro(default_project_path)
  -    except (ImportError, ModuleNotFoundError):
  -        logger.error("Kedro appears not to be installed in your current environment.")
  -    except Exception:  # pylint: disable=broad-except
  +    if default_project_path is None:
           logger.warning(
               "Kedro extension was registered but couldn't find a Kedro project. "
               "Make sure you run '%reload_kedro <project_root>'."
           )
  +        return
  +
  +    reload_kedro(default_project_path)
  
verification_info: {"golden_diff": "diff --git a/kedro/extras/extensions/ipython.py b/kedro/extras/extensions/ipython.py\n--- a/kedro/extras/extensions/ipython.py\n+++ b/kedro/extras/extensions/ipython.py\n@@ -1,4 +1,4 @@\n-# pylint: disable=import-outside-toplevel,global-statement,invalid-name\n+# pylint: disable=import-outside-toplevel,global-statement,invalid-name,too-many-locals\n \"\"\"\n This script creates an IPython extension to load Kedro-related variables in\n local scope.\n@@ -8,9 +8,6 @@\n from pathlib import Path\n from typing import Any, Dict\n \n-from IPython import get_ipython\n-from IPython.core.magic import needs_local_scope, register_line_magic\n-\n logger = logging.getLogger(__name__)\n default_project_path = Path.cwd()\n \n@@ -39,9 +36,10 @@\n ):\n     \"\"\"Line magic which reloads all Kedro default variables.\n     Setting the path will also make it default for subsequent calls.\n-\n-\n     \"\"\"\n+    from IPython import get_ipython\n+    from IPython.core.magic import needs_local_scope, register_line_magic\n+\n     from kedro.framework.cli import load_entry_points\n     from kedro.framework.project import LOGGING  # noqa # pylint:disable=unused-import\n     from kedro.framework.project import configure_project, pipelines\n@@ -63,7 +61,6 @@\n     session = KedroSession.create(\n         metadata.package_name, default_project_path, env=env, extra_params=extra_params\n     )\n-    logger.debug(\"Loading the context from %s\", default_project_path)\n     context = session.load_context()\n     catalog = context.catalog\n \n@@ -95,12 +92,11 @@\n \n     default_project_path = _find_kedro_project(Path.cwd())\n \n-    try:\n-        reload_kedro(default_project_path)\n-    except (ImportError, ModuleNotFoundError):\n-        logger.error(\"Kedro appears not to be installed in your current environment.\")\n-    except Exception:  # pylint: disable=broad-except\n+    if default_project_path is None:\n         logger.warning(\n             \"Kedro extension was registered but couldn't find a Kedro project. \"\n             \"Make sure you run '%reload_kedro <project_root>'.\"\n         )\n+        return\n+\n+    reload_kedro(default_project_path)\n", "issue": "Improve Jupyter workflow when configuration is broken\n## Description\r\n> Is your feature request related to a problem? A clear and concise description of what the problem is: \"I'm always frustrated when ...\"\r\n\r\nUsing the spaceflights demo on 0.18.1 if I open a `kedro jupyter notebook` session and write `catalog.list()` I will get the following:\r\n\r\n![image](https://user-images.githubusercontent.com/35801847/172139364-e37f8a47-69cf-4749-9ab4-3a9e55ede72e.png)\r\n\r\nIf I break the `catalog.yml` file so that it is unparsable and run `kedro catalog list` (or any other command like `kedro run` I will get a helpful parse error in the terminal: \r\n\r\n<img width=\"654\" alt=\"image\" src=\"https://user-images.githubusercontent.com/35801847/172139490-a079095e-52d7-4c80-a8d3-15c5a675239e.png\">\r\n\r\nHowever, if I start a `kedro jupyter notebook` session in this state, I get no warning or messaging that Kedro is unable to create the `catalog`, `session` and other global variables. As a user I get this confusing state where the `catalog` is no longer available to me:\r\n\r\n<img width=\"636\" alt=\"image\" src=\"https://user-images.githubusercontent.com/35801847/172139614-8dabbc13-38a4-4785-9afe-bbddf77b974a.png\">\r\n\r\n\r\n## Context\r\n> Why is this change important to you? How would you use it? How can it benefit other users?\r\n\r\nI think novice users can get stuck here with no direction as to why the catalog is not available.\r\n\r\n## Possible Implementation\r\n\r\nSurface warning to the jupyter context, perhaps even make a dummy `catalog`, `context`, `session` objects available that expose the log message when called...\n", "before_files": [{"content": "# pylint: disable=import-outside-toplevel,global-statement,invalid-name\n\"\"\"\nThis script creates an IPython extension to load Kedro-related variables in\nlocal scope.\n\"\"\"\nimport logging\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict\n\nfrom IPython import get_ipython\nfrom IPython.core.magic import needs_local_scope, register_line_magic\n\nlogger = logging.getLogger(__name__)\ndefault_project_path = Path.cwd()\n\n\ndef _remove_cached_modules(package_name):\n    to_remove = [mod for mod in sys.modules if mod.startswith(package_name)]\n    # `del` is used instead of `reload()` because: If the new version of a module does not\n    # define a name that was defined by the old version, the old definition remains.\n    for module in to_remove:\n        del sys.modules[module]  # pragma: no cover\n\n\ndef _find_kedro_project(current_dir: Path):  # pragma: no cover\n    from kedro.framework.startup import _is_project\n\n    while current_dir != current_dir.parent:\n        if _is_project(current_dir):\n            return current_dir\n        current_dir = current_dir.parent\n\n    return None\n\n\ndef reload_kedro(\n    path: str = None, env: str = None, extra_params: Dict[str, Any] = None\n):\n    \"\"\"Line magic which reloads all Kedro default variables.\n    Setting the path will also make it default for subsequent calls.\n\n\n    \"\"\"\n    from kedro.framework.cli import load_entry_points\n    from kedro.framework.project import LOGGING  # noqa # pylint:disable=unused-import\n    from kedro.framework.project import configure_project, pipelines\n    from kedro.framework.session import KedroSession\n    from kedro.framework.startup import bootstrap_project\n\n    # If a path is provided, set it as default for subsequent calls\n    global default_project_path\n    if path:\n        default_project_path = Path(path).expanduser().resolve()\n        logger.info(\"Updated path to Kedro project: %s\", default_project_path)\n    else:\n        logger.info(\"No path argument was provided. Using: %s\", default_project_path)\n\n    metadata = bootstrap_project(default_project_path)\n    _remove_cached_modules(metadata.package_name)\n    configure_project(metadata.package_name)\n\n    session = KedroSession.create(\n        metadata.package_name, default_project_path, env=env, extra_params=extra_params\n    )\n    logger.debug(\"Loading the context from %s\", default_project_path)\n    context = session.load_context()\n    catalog = context.catalog\n\n    get_ipython().push(\n        variables={\n            \"context\": context,\n            \"catalog\": catalog,\n            \"session\": session,\n            \"pipelines\": pipelines,\n        }\n    )\n\n    logger.info(\"Kedro project %s\", str(metadata.project_name))\n    logger.info(\n        \"Defined global variable 'context', 'session', 'catalog' and 'pipelines'\"\n    )\n\n    for line_magic in load_entry_points(\"line_magic\"):\n        register_line_magic(needs_local_scope(line_magic))\n        logger.info(\"Registered line magic '%s'\", line_magic.__name__)  # type: ignore\n\n\ndef load_ipython_extension(ipython):\n    \"\"\"Main entry point when %load_ext is executed\"\"\"\n\n    global default_project_path\n\n    ipython.register_magic_function(reload_kedro, \"line\", \"reload_kedro\")\n\n    default_project_path = _find_kedro_project(Path.cwd())\n\n    try:\n        reload_kedro(default_project_path)\n    except (ImportError, ModuleNotFoundError):\n        logger.error(\"Kedro appears not to be installed in your current environment.\")\n    except Exception:  # pylint: disable=broad-except\n        logger.warning(\n            \"Kedro extension was registered but couldn't find a Kedro project. \"\n            \"Make sure you run '%reload_kedro <project_root>'.\"\n        )\n", "path": "kedro/extras/extensions/ipython.py"}], "after_files": [{"content": "# pylint: disable=import-outside-toplevel,global-statement,invalid-name,too-many-locals\n\"\"\"\nThis script creates an IPython extension to load Kedro-related variables in\nlocal scope.\n\"\"\"\nimport logging\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict\n\nlogger = logging.getLogger(__name__)\ndefault_project_path = Path.cwd()\n\n\ndef _remove_cached_modules(package_name):\n    to_remove = [mod for mod in sys.modules if mod.startswith(package_name)]\n    # `del` is used instead of `reload()` because: If the new version of a module does not\n    # define a name that was defined by the old version, the old definition remains.\n    for module in to_remove:\n        del sys.modules[module]  # pragma: no cover\n\n\ndef _find_kedro_project(current_dir: Path):  # pragma: no cover\n    from kedro.framework.startup import _is_project\n\n    while current_dir != current_dir.parent:\n        if _is_project(current_dir):\n            return current_dir\n        current_dir = current_dir.parent\n\n    return None\n\n\ndef reload_kedro(\n    path: str = None, env: str = None, extra_params: Dict[str, Any] = None\n):\n    \"\"\"Line magic which reloads all Kedro default variables.\n    Setting the path will also make it default for subsequent calls.\n    \"\"\"\n    from IPython import get_ipython\n    from IPython.core.magic import needs_local_scope, register_line_magic\n\n    from kedro.framework.cli import load_entry_points\n    from kedro.framework.project import LOGGING  # noqa # pylint:disable=unused-import\n    from kedro.framework.project import configure_project, pipelines\n    from kedro.framework.session import KedroSession\n    from kedro.framework.startup import bootstrap_project\n\n    # If a path is provided, set it as default for subsequent calls\n    global default_project_path\n    if path:\n        default_project_path = Path(path).expanduser().resolve()\n        logger.info(\"Updated path to Kedro project: %s\", default_project_path)\n    else:\n        logger.info(\"No path argument was provided. Using: %s\", default_project_path)\n\n    metadata = bootstrap_project(default_project_path)\n    _remove_cached_modules(metadata.package_name)\n    configure_project(metadata.package_name)\n\n    session = KedroSession.create(\n        metadata.package_name, default_project_path, env=env, extra_params=extra_params\n    )\n    context = session.load_context()\n    catalog = context.catalog\n\n    get_ipython().push(\n        variables={\n            \"context\": context,\n            \"catalog\": catalog,\n            \"session\": session,\n            \"pipelines\": pipelines,\n        }\n    )\n\n    logger.info(\"Kedro project %s\", str(metadata.project_name))\n    logger.info(\n        \"Defined global variable 'context', 'session', 'catalog' and 'pipelines'\"\n    )\n\n    for line_magic in load_entry_points(\"line_magic\"):\n        register_line_magic(needs_local_scope(line_magic))\n        logger.info(\"Registered line magic '%s'\", line_magic.__name__)  # type: ignore\n\n\ndef load_ipython_extension(ipython):\n    \"\"\"Main entry point when %load_ext is executed\"\"\"\n\n    global default_project_path\n\n    ipython.register_magic_function(reload_kedro, \"line\", \"reload_kedro\")\n\n    default_project_path = _find_kedro_project(Path.cwd())\n\n    if default_project_path is None:\n        logger.warning(\n            \"Kedro extension was registered but couldn't find a Kedro project. \"\n            \"Make sure you run '%reload_kedro <project_root>'.\"\n        )\n        return\n\n    reload_kedro(default_project_path)\n", "path": "kedro/extras/extensions/ipython.py"}]}