### 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
from ansible.parsing.yaml.objects import AnsibleUnicode
from ansible.plugins import AnsiblePlugin, get_plugin_class
from ansible.utils.color import stringc
from ansible.utils.display import Display
from ansible.utils.unsafe_proxy import AnsibleUnsafeText, NativeJinjaUnsafeText
from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
import yaml
global_display = Display()
__all__ = ["CallbackBase"]
_DEBUG_ALLOWED_KEYS = frozenset(('msg', 'exception', 'warnings', 'deprecations'))
_YAML_TEXT_TYPES = (text_type, AnsibleUnicode, AnsibleUnsafeText, NativeJinjaUnsafeText)
_YAML_BREAK_CHARS = '\n\x85\u2028\u2029'  
_SPACE_BREAK_RE = re.compile(fr' +([{_YAML_BREAK_CHARS}])')
class _AnsibleCallbackDumper(AnsibleDumper):
    def __init__(self, lossy=False):
        self._lossy = lossy
    def __call__(self, *args, **kwargs):
        
        
        
        super().__init__(*args, **kwargs)
        return self
def _should_use_block(scalar):
    """Returns true if string should be in block format based on the existence of various newline separators"""
    
    for ch in _YAML_BREAK_CHARS:
        if ch in scalar:
            return True
    return False
class _SpecialCharacterTranslator: