Repository: nvaccess/nvda

Issue:
Say all on Desktop raises an error
### Steps to reproduce:
1. Focus the desktop.
2. Invoke caret say all

### Actual behavior:
The following error is raised:

```
ERROR - scriptHandler.executeScript (15:54:57.769):
error executing script: <bound method GlobalCommands.script_sayAll of <globalCommands.GlobalCommands object at 0x05875770>> with gesture 'NVDA+a'
Traceback (most recent call last):
  File "scriptHandler.pyc", line 190, in executeScript
  File "globalCommands.pyc", line 1334, in script_sayAll
  File "sayAllHandler.pyc", line 79, in readText
  File "sayAllHandler.pyc", line 119, in nextLine
AttributeError: '_TextReader' object has no attribute 'reader'
ERROR - stderr (15:54:57.779):
Exception ignored in:
ERROR - stderr (15:54:57.790):
<function _TextReader.__del__ at 0x0462F390>
ERROR - stderr (15:54:57.803):
Traceback (most recent call last):
ERROR - stderr (15:54:57.815):
  File "sayAllHandler.pyc", line 213, in __del__
ERROR - stderr (15:54:57.827):
  File "sayAllHandler.pyc", line 206, in stop
ERROR - stderr (15:54:57.839):
AttributeError
ERROR - stderr (15:54:57.851):
:
ERROR - stderr (15:54:57.863):
'_TextReader' object has no attribute 'reader'
```

### Expected behavior:
NO error

### System configuration
#### NVDA installed/portable/running from source:
Installed

#### NVDA version:
threshold-18069

#### Windows version:
Windows 10 1903 build 18362.239



Discussion:
This is a one line fix.

if api.getCaretObject() fails, the reader should be set to None. Then, nextLine will automatically abort. Alternatively, we should raise the error and catch it where we call sayAllhandler, but that differs from the implementation in master.
Unfortunately it's not fixed for me with latest Alpha.
When pressing NVDA + down arrow on desktop error sound plays and the following is in the log:

ERROR - stderr (11:34:21.050) - MainThread (6084):
Exception ignored in:
ERROR - stderr (11:34:21.060) - MainThread (6084):
<function _TextReader.__del__ at 0x033A4150>
ERROR - stderr (11:34:21.080) - MainThread (6084):
Traceback (most recent call last):
ERROR - stderr (11:34:21.100) - MainThread (6084):
  File "sayAllHandler.pyc", line 252, in __del__
ERROR - stderr (11:34:21.120) - MainThread (6084):
  File "sayAllHandler.pyc", line 245, in stop
ERROR - stderr (11:34:21.140) - MainThread (6084):
AttributeError
ERROR - stderr (11:34:21.160) - MainThread (6084):
:
ERROR - stderr (11:34:21.180) - MainThread (6084):
'_TextReader' object has no attribute 'reader'
@feerrenrut Could you please reopen?

Resolving patch:
diff --git a/source/sayAllHandler.py b/source/sayAllHandler.py
--- a/source/sayAllHandler.py
+++ b/source/sayAllHandler.py
@@ -109,7 +109,7 @@ class _TextReader(object):
 	def __init__(self, cursor):
 		self.cursor = cursor
 		self.trigger = SayAllProfileTrigger()
-		self.trigger.enter()
+		self.reader = None
 		# Start at the cursor.
 		if cursor == CURSOR_CARET:
 			try:
@@ -118,6 +118,8 @@ def __init__(self, cursor):
 				raise NotImplementedError("Unable to make TextInfo: " + str(e))
 		else:
 			self.reader = api.getReviewPosition()
+		# #10899: SayAll profile can't be activated earlier because they may not be anything to read
+		self.trigger.enter()
 		self.speakTextInfoState = speech.SpeakTextInfoState(self.reader.obj)
 		self.numBufferedLines = 0
 


Test patch: