Repository: spyder-ide/spyder

Issue:
Spyder crashes due to uncaught FileNotFoundError on startup
## Problem Description

Spyder doesn't handle some nonexistent files properly when it tries to reopen files on startup. Usual nonExistingFiles are just not opened (fine) while certain files cause a crash. 

The problematic path is unusual: It has a Directory Junction pointing to a Symlink whose target is on a network drive that is unavailable during the crash.
I noticed pythons `open()` on the file takes on the order of seconds until it raises, my guess is that the underlying syscall itself is taking so long.

My guess is that the problem is like a race condition in that it is usually caught. However I guess the location of the problem in spyder's code is so clear that it is possible to add more exception handling fixing the issue, even if the error cannot be reproduced.
The code that lacks some exception handling is most likely in spyder\plugins\editor\widgets\editor.py around line 1500 in set_current_filename() or a bit further down. See traceback.

- local nonExistingFile: fine
- nonExistingFile on a windows network drive: fine
- (on local drive:) Directory  Junction -> symlink to directory on unavailable network drive -> consequently nonExistingFile : raises.

The error was reproduced with a fresh ~/.spyder-py3 where in the config/transient.py the problematic filename was inserted.

### What steps reproduce the problem?

1. put a problematic non-existent file into `~/spyder-py/config/transient.ini` -> [editor] section -> filenames list.
2. open spyder. Spyder crashes

### Paste Traceback/Error Below (if applicable)

```python-traceback
C:\WINDOWS\system32>python -m spyder.app.start
No QCoreApplication instance found. Application patches not applied. You have to call load_stylesheet function after instantiation of QApplication to take effect.
Pruned plugin: outline_explorer
Missing requirement: completions
Restart plugins pruning by REQUIRES check
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\ntpath.py", line 647, in realpath
    path = _getfinalpathname(path)
FileNotFoundError: [WinError 53] The network path was not found: 'C:\\Links\\nonExisting.py'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Program Files\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Program Files\Python39\lib\site-packages\spyder\app\start.py", line 231, in <module>
    main()
  File "C:\Program Files\Python39\lib\site-packages\spyder\app\start.py", line 213, in main
    mainwindow.main(options, args)
  File "C:\Program Files\Python39\lib\site-packages\spyder\app\mainwindow.py", line 2310, in main
    mainwindow = create_window(app, splash, options, args)
  File "C:\Program Files\Python39\lib\site-packages\spyder\app\mainwindow.py", line 2171, in create_window
    main.post_visible_setup()
  File "C:\Program Files\Python39\lib\site-packages\spyder\app\mainwindow.py", line 1303, in post_visible_setup
    self.editor.setup_open_files(close_previous_files=False)
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\plugin.py", line 3165, in setup_open_files
    self.load(filenames[index::-1], goto=clines[index::-1],
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\plugin.py", line 2190, in load
    current_editor = self.set_current_filename(filename,
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\plugin.py", line 1720, in set_current_filename
    return editorstack.set_current_filename(filename, focus)
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\widgets\editor.py", line 1507, in set_current_filename
    index = self.has_filename(filename)
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\widgets\editor.py", line 1501, in has_filename
    if fixpath(filename) == fixpath(finfo.filename):
  File "C:\Program Files\Python39\lib\site-packages\spyder\plugins\editor\widgets\editor.py", line 1499, in <lambda>
    fixpath = lambda path: osp.normcase(osp.realpath(path))
  File "C:\Program Files\Python39\lib\ntpath.py", line 651, in realpath
    path = _getfinalpathname_nonstrict(path)
  File "C:\Program Files\Python39\lib\ntpath.py", line 601, in _getfinalpathname_nonstrict
    path = _getfinalpathname(path)
FileNotFoundError: [WinError 53] The network path was not found:  'C:\\Links\\nonExisting.py'
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\spyder\widgets\dock.py", line 253, in install_tab_event_filter
    tabbars = self.main.findChildren(QTabBar)
RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
```

## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 5.0.3
* Python version: 3.9.5
* Qt version: 5.15.2
* PyQt version: 5.15.4
* Operating System name/version: Windows 10

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```

# Mandatory:
atomicwrites >=1.2.0          :  1.4.0 (OK)
chardet >=2.0.0               :  4.0.0 (OK)
cloudpickle >=0.5.0           :  1.6.0 (OK)
cookiecutter >=1.6.0          :  1.7.3 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.1.0 (OK)
IPython >=7.6.0               :  7.23.1 (OK)
jedi =0.17.2                  :  0.17.2 (OK)
jsonschema >=3.2.0            :  3.2.0 (OK)
keyring >=17.0.0              :  23.0.1 (OK)
nbconvert >=4.0               :  6.0.7 (OK)
numpydoc >=0.6.0              :  1.1.0 (OK)
paramiko >=2.4.0              :  2.7.2 (OK)
parso =0.7.0                  :  0.7.0 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.8.0 (OK)
pygments >=2.0                :  2.9.0 (OK)
pylint >=1.0                  :  2.8.2 (OK)
pyls >=0.36.2;<1.0.0          :  0.36.2 (OK)
pyls_black >=0.4.6            :  0.4.6 (OK)
pyls_spyder >=0.3.2;<0.4.0    :  0.3.2 (OK)
qdarkstyle =3.0.2             :  3.0.2 (OK)
qstylizer >=0.1.10            :  0.2.0 (OK)
qtawesome >=1.0.2             :  1.0.2 (OK)
qtconsole >=5.1.0             :  5.1.0 (OK)
qtpy >=1.5.0                  :  1.9.0 (OK)
rtree >=0.9.7                 :  0.9.7 (OK)
setuptools >=39.0.0           :  57.0.0 (OK)
sphinx >=0.6.6                :  4.0.2 (OK)
spyder_kernels >=2.0.3;<2.1.0 :  2.0.3 (OK)
textdistance >=4.2.0          :  4.2.1 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3;<2.0.0      :  1.0.2 (OK)
zmq >=17                      :  22.1.0 (OK)

# Optional:
cython >=0.21                 :  None (NOK)
matplotlib >=2.0.0            :  3.4.2 (OK)
numpy >=1.7                   :  1.20.3 (OK)
pandas >=1.1.1                :  1.2.4 (OK)
scipy >=0.17.0                :  1.6.3 (OK)
sympy >=0.7.3                 :  None (NOK)

```



Discussion:
Thanks for reporting @arian-f. You said

> However I guess the location of the problem in spyder's code is so clear that it is possible to add more exception handling fixing the issue, even if the error cannot be reproduced.

I was thinking exactly the same. We'll add a try/except to avoid showing this error then and add it to our next version (5.0.4), to be released shortly.

Resolving patch:
diff --git a/spyder/plugins/editor/widgets/editor.py b/spyder/plugins/editor/widgets/editor.py
--- a/spyder/plugins/editor/widgets/editor.py
+++ b/spyder/plugins/editor/widgets/editor.py
@@ -1504,7 +1504,15 @@ def has_filename(self, filename):
 
     def set_current_filename(self, filename, focus=True):
         """Set current filename and return the associated editor instance."""
-        index = self.has_filename(filename)
+        # This is necessary to catch an error on Windows for files in a
+        # directory junction pointing to a symlink whose target is on a
+        # network drive that is unavailable at startup.
+        # Fixes spyder-ide/spyder#15714
+        try:
+            index = self.has_filename(filename)
+        except FileNotFoundError:
+            index = None
+
         if index is not None:
             if focus:
                 self.set_stack_index(index)


Test patch: