Repository: Delgan/loguru

Issue:
Make `.catch()` context manager async compatible
Hi,

First, thanks for a lot for loguru :)

I have a piece of code like this:

```python
import httpx
from loguru import logger as loguru_logger

@app.get("/")  # some fastapi route
async def my_route(foo, bar):
    logger = loguru_logger.bind(foo=foo, bar=bar)  # add some context to my logger
    with logger.catch():  # first context manager
        async with httpx.AsyncClient() as client:  # second context manager
            r = await client.get('https://www.example.com/')
            # do stuff...
```

In python, it's possible to chain context managers: 
```python
with A() as X, B() as Y, C() as Z:
    do_something()
```

But I don't think it's possible to mix async and sync context managers.

So I wonder if we could make the class `Catcher` async compatible? I think that it would require implementing `__aenter__` and `__aexit__`

This feature would allow this:

```python
import httpx
from loguru import logger as loguru_logger

@app.get("/")  # some fastapi route
async def my_route(foo, bar):
    logger = loguru_logger.bind(foo=foo, bar=bar)  # add some context to my logger
    async with logger.catch(), httpx.AsyncClient() as client:  # all in one line
        r = await client.get('https://www.example.com/')
        # do stuff...
```

Thanks

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 1f575b8..1d48efc 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -7,6 +7,7 @@
 - Update the default log format to include the timezone offset since it produces less ambiguous logs (`#856 <https://github.com/Delgan/loguru/pull/856>`_, thanks `@tim-x-y-z <https://github.com/tim-x-y-z>`_).
 - Honor the ``NO_COLOR`` environment variable to disable color output by default if ``colorize`` is not provided (`#1178 <https://github.com/Delgan/loguru/issues/1178>`_).
 - Add requirement for ``TERM`` environment variable not to be ``"dumb"`` to enable colorization (`#1287 <https://github.com/Delgan/loguru/pull/1287>`_, thanks `@snosov1 <https://github.com/snosov1>`_).
+- Make ``logger.catch()`` usable as an asynchronous context manager (`#1084 <https://github.com/Delgan/loguru/issues/1084>`_).
 - Make ``logger.catch()`` compatible with asynchronous generators (`#1302 <https://github.com/Delgan/loguru/issues/1302>`_).
 
 
diff --git a/loguru/_logger.py b/loguru/_logger.py
index 5c2ba54..7f17f1a 100644
--- a/loguru/_logger.py
+++ b/loguru/_logger.py
@@ -1333,6 +1333,12 @@ class Logger:
                 functools.update_wrapper(catch_wrapper, function)
                 return catch_wrapper
 
+            async def __aenter__(self):
+                return self.__enter__()
+
+            async def __aexit__(self, type_, value, traceback_):
+                return self.__exit__(type_, value, traceback_)
+
         return Catcher(False)
 
     def opt(


Test patch:
diff --git a/tests/test_exceptions_catch.py b/tests/test_exceptions_catch.py
index 71ebc29..f06b831 100644
--- a/tests/test_exceptions_catch.py
+++ b/tests/test_exceptions_catch.py
@@ -439,6 +439,15 @@ def test_default_with_coroutine():
     assert asyncio.run(foo()) == 42
 
 
+def test_async_context_manager():
+    async def coro():
+        async with logger.catch():
+            return 1 / 0
+        return 1
+
+    assert asyncio.run(coro()) == 1
+
+
 def test_error_when_decorating_class_without_parentheses():
     with pytest.raises(TypeError):