Repository: sanic-org/sanic

Issue:
In multiworker mode better error message if no apps
If a developer does not define their app so that a worker process can access it, they will receive a `KeyError` when Sanic tries to access it from the registry.

For example, that would happen if an app only was instantiated on the main process:

```python
if __name__ == "__main__":
    app = Sanic(...)
    app.run()
```

The solution to this is usually either to move the instantiation outside that block, or to use an [`AppLoader`](https://sanic.dev/en/guide/deployment/app-loader.html).

We should provide a better error message from within a worker process if an app cannot be found in a registry.

Discussion:
ahopkins: Thanks, but I think the way I was planning to handle this was to switch the order of socket config, in which case the existing message should handle this.
codecov[bot]: # [Codecov](https://codecov.io/gh/sanic-org/sanic/pull/2585?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) Report
Base: **88.093**% // Head: **88.018**% // Decreases project coverage by **`-0.075%`** :warning:
> Coverage data is based on head [(`68d74c2`)](https://codecov.io/gh/sanic-org/sanic/pull/2585?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) compared to base [(`82421e7`)](https://codecov.io/gh/sanic-org/sanic/commit/82421e7efc9d53f436ecbc2ca37a91f984847a69?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).
> Patch has no changes to coverable lines.

<details><summary>Additional details and impacted files</summary>


```diff
@@              Coverage Diff              @@
##              main     #2585       +/-   ##
=============================================
- Coverage   88.093%   88.018%   -0.076%     
=============================================
  Files           71        71               
  Lines         5333      5333               
  Branches       893       893               
=============================================
- Hits          4698      4694        -4     
- Misses         459       461        +2     
- Partials       176       178        +2     
```


| [Impacted Files](https://codecov.io/gh/sanic-org/sanic/pull/2585?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org) | Coverage Δ | |
|---|---|---|
| [sanic/server/websockets/impl.py](https://codecov.io/gh/sanic-org/sanic/pull/2585/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org#diff-c2FuaWMvc2VydmVyL3dlYnNvY2tldHMvaW1wbC5weQ==) | `37.115% <0.000%> (-0.946%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/sanic-org/sanic/pull/2585?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=sanic-org).


Patch:
diff --git a/sanic/app.py b/sanic/app.py
index cb6f76b3..e064f70f 100644
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -1453,7 +1453,14 @@ class Sanic(BaseSanic, StartupMixin, metaclass=TouchUpMeta):
                 return cls.get_app("__mp_main__", force_create=force_create)
             if force_create:
                 return cls(name)
-            raise SanicException(f'Sanic app name "{name}" not found.')
+            raise SanicException(
+                f"Sanic app name '{name}' not found.\n"
+                "App instantiation must occur outside "
+                "if __name__ == '__main__' "
+                "block or by using an AppLoader.\nSee "
+                "https://sanic.dev/en/guide/deployment/app-loader.html"
+                " for more details."
+            )
 
     @classmethod
     def _check_uvloop_conflict(cls) -> None:


Test patch:
diff --git a/tests/test_app.py b/tests/test_app.py
index 0e71f9f7..538fb893 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -347,7 +347,13 @@ def test_app_registry_retrieval_from_multiple():
 
 def test_get_app_does_not_exist():
     with pytest.raises(
-        SanicException, match='Sanic app name "does-not-exist" not found.'
+        SanicException,
+        match="Sanic app name 'does-not-exist' not found.\n"
+            "App instantiation must occur outside "
+            "if __name__ == '__main__' "
+            "block or by using an AppLoader.\nSee "
+            "https://sanic.dev/en/guide/deployment/app-loader.html"
+            " for more details."
     ):
         Sanic.get_app("does-not-exist")