Checklist
Streamlink version
Latest stable release
Description
While trying to use the SSLKEYLOGFILE feature of python's SSL module, I set the value of this env variable to an invalid path string (I added quotes around the path which are not expected by the Windows API) which gets rejected by openssl/kernel layer.
This raises a specific kind of error (obtained by running the process in Pdb):
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 701, in urlopen
httplib_response = self._make_request(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 384, in _make_request
self._validate_conn(conn)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 1013, in _validate_conn
conn.connect()
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 402, in connect
self.ssl_context = create_urllib3_context(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\ssl_.py", line 350, in create_urllib3_context
context.keylog_filename = sslkeylogfile
OSError: [Errno 22] Invalid argument: '"C:\\Users\\Admin\\SSLKEYLOGFILE.txt"'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 439, in send
resp = conn.urlopen(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 757, in urlopen
retries = retries.increment(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\retry.py", line 532, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\packages\six.py", line 769, in reraise
raise value.with_traceback(tb)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 701, in urlopen
httplib_response = self._make_request(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 384, in _make_request
self._validate_conn(conn)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 1013, in _validate_conn
conn.connect()
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connection.py", line 402, in connect
self.ssl_context = create_urllib3_context(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\ssl_.py", line 350, in create_urllib3_context
context.keylog_filename = sslkeylogfile
urllib3.exceptions.ProtocolError: ('Connection aborted.', OSError(22, 'Invalid argument'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\streamlink\plugin\api\http_session.py", line 153, in request
res = super().request(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 498, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', OSError(22, 'Invalid argument'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\streamlink\plugins\twitch.py", line 619, in _access_token
sig, token = self.api.access_token(is_live, channel_or_vod)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\streamlink\plugins\twitch.py", line 424, in access_token
return self.call(query, schema=validate.Schema(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\streamlink\plugins\twitch.py", line 264, in call
res = self.session.http.post(
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 590, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\streamlink\plugin\api\http_session.py", line 172, in request
raise err
streamlink.exceptions.PluginError: Unable to open URL: https://gql.twitch.tv/gql (('Connection aborted.', OSError(22, 'Invalid argument')))
However this relatively clearly communicated error is swallowed by ~the twitch plugin code~a generic streamlink exception, and is converted into a vague NoStreamsError
here:
def _access_token(self, is_live, channel_or_vod):
try:
sig, token = self.api.access_token(is_live, channel_or_vod)
except (PluginError, TypeError):
raise NoStreamsError(self.url)
...which eventually results in the end of the process with only a single and misleading message like this:
error: No playable streams found on this URL: twitch.tv/insert_live_channel
While the root cause in this case is user error, I think it's worth noting that the exception catch clause is way too broad; unexpected exceptions bubbling up from the ssl/os/socket layers shouldn't be treated as "no stream available to play", they should bubble up to the top and be properly logged to the end user in some form.
My guess is that the "true" no-stream-to-play case raises a few or just one specific kind of (inner)exception; the best practice would be for only those to be caught, while everything else should be raised further up.
Debug log
Loaded config from deprecated path, see CLI docs for how to migrate: C:\Users\Admin\AppData\Roaming\streamlink\streamlinkrc
[cli][warning] Loaded config from deprecated path, see CLI docs for how to migrate: C:\Users\Admin\AppData\Roaming\streamlink\streamlinkrc
[cli][debug] OS: Windows 10
[cli][debug] Python: 3.10.8
[cli][debug] Streamlink: 5.1.2
[cli][debug] Dependencies:
[cli][debug] certifi: 2021.10.8
[cli][debug] isodate: 0.6.0
[cli][debug] lxml: 4.6.4
[cli][debug] pycountry: 20.7.3
[cli][debug] pycryptodome: 3.11.0
[cli][debug] PySocks: 1.7.1
[cli][debug] requests: 2.26.0
[cli][debug] urllib3: 1.26.7
[cli][debug] websocket-client: 1.2.1
[cli][debug] Arguments:
[cli][debug] url=twitch.tv/insert_live_channel
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player="C:\Program Files\MPC-HC\mpc-hc64.exe"
[cli][debug] --twitch-low-latency=True
[cli][info] Found matching plugin twitch for URL twitch.tv/insert_live_channel
[plugins.twitch][debug] Getting live HLS streams for insert_live_channel
error: No playable streams found on this URL: twitch.tv/insert_live_channel
API: http-session API: validate