### Summary

If a module calls `fail_json()` and provides `exception=None`, this will crash every callback that uses `_handle_exception` from `CallbackBase`: if verbosity is < 3, it will try to call `split` on `None`, and otherwise it will try to concatenate a string with `None` (which results in `TypeError`).

### Issue Type

Bug Report

### Component Name

lib/ansible/plugins/callback/__init__.py

### Ansible Version

```console
devel
```


### Configuration

```console
*
```


### OS / Environment

*

### Steps to Reproduce

*

### Expected Results

*

### Actual Results

```console
*
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
''' display warnings, if enabled and any exist in the result '''
        if C.ACTION_WARNINGS:
            if 'warnings' in res and res['warnings']:
                for warning in res['warnings']:
                    self._display.warning(warning)
                del res['warnings']
            if 'deprecations' in res and res['deprecations']:
                for warning in res['deprecations']:
                    self._display.deprecated(**warning)
                del res['deprecations']
    def _handle_exception(self, result, use_stderr=False):
        if 'exception' in result:
            msg = "An exception occurred during task execution. "
            if self._display.verbosity < 3:
                
                error = result['exception'].strip().split('\n')[-1]
                msg += "To see the full traceback, use -vvv. The error was: %s" % error
            else:
                msg = "The full traceback is:\n" + result['exception']
                del result['exception']
            self._display.display(msg, color=C.COLOR_ERROR, stderr=use_stderr)
    def _serialize_diff(self, diff):