Repository: PyCQA/flake8

Issue:
A missing explicitly specified config file is silently ignored
*Please describe how you installed Flake8*

```console
$ virtualenv venv
$ . venv/bin/activate
$ pip install flake8
```

*Please provide the exact, unmodified output of `flake8 --bug-report`*

```cnosole
$ flake8 --bug-report
{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.8.8",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "mccabe",
      "version": "0.6.1"
    },
    {
      "is_local": false,
      "plugin": "pycodestyle",
      "version": "2.8.0"
    },
    {
      "is_local": false,
      "plugin": "pyflakes",
      "version": "2.4.0"
    }
  ],
  "version": "4.0.1"
}
```

*Please describe the problem or feature*

flake8 silently ignores the specified config file if it is missing

```console
$ rm -f foo
$ touch t.py
$ flake8 --config foo t.py
$ echo $?
0
```

*If this is a bug report, please explain with examples (and example code) what you expected to happen and what actually happened.*

An error should be raised if the specified config file is missing.

Looks like the culprit is `configparser.read()`: ["If a file named in filenames cannot be opened, that file will be ignored"](https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read)

Comments:

Patch:
diff --git a/src/flake8/options/config.py b/src/flake8/options/config.py
index d7519df..7cba936 100644
--- a/src/flake8/options/config.py
+++ b/src/flake8/options/config.py
@@ -8,6 +8,7 @@ from typing import List
 from typing import Optional
 from typing import Tuple
 
+from flake8 import exceptions
 from flake8.options.manager import OptionManager
 
 LOG = logging.getLogger(__name__)
@@ -60,7 +61,10 @@ def load_config(
 
     cfg = configparser.RawConfigParser()
     if config is not None:
-        cfg.read(config)
+        if not cfg.read(config):
+            raise exceptions.ExecutionError(
+                f"The specified config file does not exist: {config}"
+            )
         cfg_dir = os.path.dirname(config)
     else:
         cfg_dir = pwd


Test patch:
diff --git a/tests/integration/test_main.py b/tests/integration/test_main.py
index b351e9d..fe254b7 100644
--- a/tests/integration/test_main.py
+++ b/tests/integration/test_main.py
@@ -386,3 +386,21 @@ def test_early_keyboard_interrupt_does_not_crash(capsys):
     out, err = capsys.readouterr()
     assert out == "... stopped\n"
     assert err == ""
+
+
+def test_config_file_not_found(tmpdir, capsys):
+    """Ensure that an explicitly specified config file which is not found is an
+    error"""
+
+    expected = """\
+There was a critical error during execution of Flake8:
+The specified config file does not exist: missing.cfg
+"""
+
+    with tmpdir.as_cwd():
+        tmpdir.join("t.py").write("print('hello hello world')\n")
+        assert cli.main(["--config", "missing.cfg", "t.py"]) == 1
+
+    out, err = capsys.readouterr()
+    assert out == expected
+    assert err == ""
diff --git a/tests/unit/test_options_config.py b/tests/unit/test_options_config.py
index b288de0..c5d1476 100644
--- a/tests/unit/test_options_config.py
+++ b/tests/unit/test_options_config.py
@@ -2,6 +2,7 @@ import configparser
 
 import pytest
 
+from flake8 import exceptions
 from flake8.main.options import register_default_options
 from flake8.options import config
 from flake8.options.manager import OptionManager
@@ -164,3 +165,8 @@ def test_parse_config_ignores_unknowns(tmp_path, opt_manager, caplog):
             'Option "wat" is not registered. Ignoring.',
         )
     ]
+
+
+def test_load_config_missing_file_raises_exception(capsys):
+    with pytest.raises(exceptions.ExecutionError):
+        config.load_config("foo.cfg", [])