{"record":{"id":"dba9b38c20cfdd78","repo":"tursodatabase/turso","slug":"throw-tosqliteexception-ex-statement-sql","errorCode":null,"errorMessage":"throw ToSqliteException(ex, statement.Sql);","messagePattern":"throw ToSqliteException\\(ex, statement\\.Sql\\);","errorType":"exception","errorClass":"SqliteException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs","lineNumber":347,"sourceCode":"\n    private async Task PrepareManagedAsync(CancellationToken cancellationToken)\n    {\n        var statements = GetManagedStatements();\n        ValidateManagedParameterValues();\n        foreach (var statement in statements)\n        {\n            cancellationToken.ThrowIfCancellationRequested();\n            var sql = RewriteFacadeStatement(statement.Sql, Connection!);\n\n            using var command = CreateManagedCommand(statement, sql);\n            _activeManagedCommand = command;\n            try\n            {\n                await command.PrepareAsync(cancellationToken).ConfigureAwait(false);\n            }\n            catch (TursoException ex)\n            {\n                throw ToSqliteException(ex, statement.Sql);\n            }\n            finally\n            {\n                _activeManagedCommand = null;\n            }\n        }\n    }\n\n    private async Task<SqliteDataReader> ExecuteManagedAsync(\n        string method,\n        CommandBehavior behavior,\n        CancellationToken cancellationToken)\n    {\n        EnsureExecutable(method);\n        var statements = GetManagedStatements();\n        if (Connection!.HasOpenReader && statements.Any(IsWriteStatement))\n        {\n            await Task.Delay(TimeSpan.FromSeconds(CommandTimeout), cancellationToken).ConfigureAwait(false);","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs#L329-L365","documentation":"When SqliteCommand.Prepare() or PrepareAsync() is called on a managed (remote/embedded) command, any TursoException raised while compiling the SQL statement is converted into a standard Microsoft.Data.Sqlite SqliteException with mapped SQLite result codes. This wrapper exists so ADO.NET callers see the familiar exception type instead of a Turso-specific one. The failing SQL text is preserved for diagnostics.","triggerScenarios":"Calling Prepare()/PrepareAsync() on a SqliteCommand whose SQL contains a syntax error, references a missing table/column, or whose underlying Turso connection/stream has failed; the inner command.PrepareAsync call throws TursoException.","commonSituations":"Typos in SQL, running a query before migrations created the table, schema drift between environments, or a remote connection dropped between opening the connection and preparing the statement.","solutions":["Read the SqliteException message/SqliteErrorCode to identify the actual SQL problem (parse error, no such table, etc.) and fix the SQL or schema.","Call Prepare() only after the schema exists; run migrations before command preparation.","If the cause is a dead connection, check Connection.State and reopen/refresh the connection.","Catch SqliteException and inspect SqliteErrorCode (e.g. SQLITE_ERROR 1) for programmatic handling."],"exampleFix":"// before\nawait cmd.PrepareAsync(ct); // throws SqliteException 'no such table: users'\n// after\nawait EnsureTablesExistAsync(conn); // run DDL/migrations first\nawait cmd.PrepareAsync(ct);","handlingStrategy":"try-catch","validationCode":"if (conn.State != ConnectionState.Open) throw new InvalidOperationException(\"connection must be open before Prepare\");\n// additionally: ensure schema exists, e.g. SELECT name FROM sqlite_master WHERE name = 'mytable'","typeGuard":"static bool CanPrepare(SqliteCommand cmd) =>\n    cmd?.Connection is SqliteConnection c && c.State == ConnectionState.Open && !string.IsNullOrWhiteSpace(cmd.CommandText);","tryCatchPattern":"try\n{\n    await cmd.PrepareAsync(ct);\n}\ncatch (SqliteException ex)\n{\n    // ex.SqliteErrorCode: 1 = SQL/syntax/missing object, 5 = busy, 7 = out of memory\n    logger.LogError(ex, \"Prepare failed for: {Sql}\", cmd.CommandText);\n    throw;\n}","preventionTips":["Run schema migrations before preparing statements","Validate SQL with a parser or test fixture before shipping","Check Connection.State before every command","Keep statement text parameterized rather than string-concatenated"],"tags":["dotnet","sqlite","sql-prepare","ado-net"],"backgroundTag":"sql-query-failed","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-09-06T07:15:26.990Z","contentChangedAt":"2026-09-06T07:15:26.990Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}