Print cause of exceptions even when they have no traceback
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 8b49afe5e..e68a05b41 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -43,6 +43,7 @@ The following people have contributed to the development of Rich:
 - [Nicolas Simonds](https://github.com/0xDEC0DE)
 - [Aaron Stephens](https://github.com/aaronst)
 - [Gabriele N. Tornetta](https://github.com/p403n1x87)
+- [Nils Vu](https://github.com/nilsvu)
 - [Arian Mollik Wasi](https://github.com/wasi-master)
 - [Handhika Yanuar Pratama](https://github.com/theDreamer911)
 - [za](https://github.com/za)
diff --git a/rich/traceback.py b/rich/traceback.py
index 55acaf070..5c1ac8f4f 100644
--- a/rich/traceback.py
+++ b/rich/traceback.py
@@ -389,19 +389,17 @@ def safe_str(_object: Any) -> str:
                     del stack.frames[:]
 
             cause = getattr(exc_value, "__cause__", None)
-            if cause and cause.__traceback__:
+            if cause:
                 exc_type = cause.__class__
                 exc_value = cause
+                # __traceback__ can be None, e.g. for exceptions raised by the
+                # 'multiprocessing' module
                 traceback = cause.__traceback__
                 is_cause = True
                 continue
 
             cause = exc_value.__context__
-            if (
-                cause
-                and cause.__traceback__
-                and not getattr(exc_value, "__suppress_context__", False)
-            ):
+            if cause and not getattr(exc_value, "__suppress_context__", False):
                 exc_type = cause.__class__
                 exc_value = cause
                 traceback = cause.__traceback__

Exceptions from subprocesses raised by 'multiprocessing' don't include a traceback, so rich doesn't currently print them. They contain important information though, so this PR enables printing the exception without the traceback. This works because `walk_tb` doesn't do anything if the input is `None`.

Minimal example:

```py
import rich.traceback
import multiprocessing


def fail():
    raise ValueError


if __name__ == "__main__":
    rich.traceback.install()
    with multiprocessing.Pool() as pool:
        # The traceback printed by rich doesn't point to the function `fail`,
        # but only to code in the `multiprocessing` module. This PR fixes that.
        pool.apply(fail)
```

Note that exceptions from multiprocessing include the traceback formatted as a string in the description of the exception (see this code in multiprocessing.pool: https://github.com/python/cpython/blob/main/Lib/multiprocessing/pool.py#L57). This will be printed by rich after this PR.

## Type of changes

- [x] Bug fix
- [ ] New feature
- [ ] Documentation / docstrings
- [ ] Tests
- [ ] Other

## Checklist

- [x] I've run the latest [black](https://github.com/psf/black) with default args on new code.
- [x] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
- [x] I've added tests for new code.
- [x] I accept that @willmcgugan may be pedantic in the code review.
