Repository: pypa/pip

Issue:
Improve error message when `pip config edit` is provided an editor that doesn't exist
### Description

If you run `pip config --edit` with an editor that doesn't exist, pip presents a traceback.

### Expected behavior

`pip` would present a clear error message, about which file could not be found.

### pip version

21.3.1

### Python version

N/A

### OS

Windows

### How to Reproduce

Run `pip config edit --editor code` on a Windows machine without VSCode installed.

### Output

```sh-session
C:\Users\traveler\Desktop\pip>py -m pip config edit --editor code
ERROR: Exception:
Traceback (most recent call last):
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_internal\cli\base_command.py", line 173, in _main
    status = self.run(options, args)
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_internal\commands\configuration.py", line 128, in run
    handlers[action](options, args[1:])
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_internal\commands\configuration.py", line 225, in open_in_editor
    subprocess.check_call([editor, fname])
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 364, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 345, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\traveler\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified
```

### Code of Conduct

- [X] I agree to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/).


Discussion:

Resolving patch:
diff --git a/src/pip/_internal/commands/configuration.py b/src/pip/_internal/commands/configuration.py
--- a/src/pip/_internal/commands/configuration.py
+++ b/src/pip/_internal/commands/configuration.py
@@ -225,6 +225,10 @@ def open_in_editor(self, options: Values, args: List[str]) -> None:
 
         try:
             subprocess.check_call([editor, fname])
+        except FileNotFoundError as e:
+            if not e.filename:
+                e.filename = editor
+            raise
         except subprocess.CalledProcessError as e:
             raise PipError(
                 "Editor Subprocess exited with exit code {}".format(e.returncode)


Test patch:
diff --git a/tests/functional/test_configuration.py b/tests/functional/test_configuration.py
--- a/tests/functional/test_configuration.py
+++ b/tests/functional/test_configuration.py
@@ -140,3 +140,10 @@ def test_global_config_file(self, script: PipTestEnvironment) -> None:
         global_config_file = get_configuration_files()[kinds.GLOBAL][0]
         result = script.pip("config", "debug")
         assert f"{global_config_file}, exists:" in result.stdout
+
+    def test_editor_does_not_exist(self, script: PipTestEnvironment) -> None:
+        """Ensure that FileNotFoundError sets filename correctly"""
+        result = script.pip(
+            "config", "edit", "--editor", "notrealeditor", expect_error=True
+        )
+        assert "notrealeditor" in result.stderr