does this somehow cheat the querystore into thinking it is ok, no matter what the result ?
Queries executed with sys.sp_executesql
can definitely be logged in the Query Store as "Aborted" or "Exception." Here's a small repro. First I created a database with impractical Query Store settings:
USE [master];
GO
DROP DATABASE IF EXISTS [278067];
GO
CREATE DATABASE [278067];
ALTER DATABASE [278067] SET QUERY_STORE = ON;
ALTER DATABASE [278067]
SET QUERY_STORE
(
OPERATION_MODE = READ_WRITE,
DATA_FLUSH_INTERVAL_SECONDS = 30,
INTERVAL_LENGTH_MINUTES = 1
);
GO
USE [278067];
GO
Then I ran some .NET code that exercised the following scenarios:
- Run a normal successful query
- Run a query that errors out (in this case, it was a divide by zero)
- Run a query that returns millions of rows, and then cancel client-side before all the results have been consumed
- Run a query that returns millions of rows, and then close the connection before all the results have been consumed
- Run a query that gets blocked, and experiences a server side lock timeout
Here's how the came through in the Extended Events "rpc_completed" event:

I embedded a comment of /* Track Me */
in each of the queries so I could find them in the query store:
SELECT
qsrs.execution_type,
qsrs.execution_type_desc,
qsrsi.start_time,
qsrsi.end_time,
qsqt.query_sql_text,
qsp.query_plan
FROM sys.query_store_plan qsp
INNER JOIN sys.query_store_query qsq
ON qsp.query_id = qsq.query_id
INNER JOIN sys.query_store_query_text qsqt
ON qsqt.query_text_id = qsq.query_text_id
INNER JOIN sys.query_store_runtime_stats qsrs
ON qsrs.plan_id = qsp.plan_id
INNER JOIN sys.query_store_runtime_stats_interval qsrsi
ON qsrsi.runtime_stats_interval_id = qsrs.runtime_stats_interval_id
WHERE
qsqt.query_sql_text LIKE '%Track Me%'
AND qsqt.query_sql_text NOT LIKE '%sys.query_store_plan%';

As expected, we see Regular, Exception, and then three Aborted queries.
All that is to say that I don't think the discrepancy can be explained by the application's use of sys.sp_executesql
.
If you could elaborate more on:
- your query store settings (perhaps the queries experiencing timeouts aren't being logged)
- what specific kind of timeout the query experienced (client side connection or command timeout, lock timeout, something else)
- the extended event you used to identify the timeout
Then you might be able to get some more help tracking this down.