Launch Offer: Use codelaunch30for 30% off

SQLITE_INTERRUPT: interrupted

This error occurs when a long-running query is cancelled, typically via sqlite3_interrupt() or a timeout. Learn how to handle query cancellation gracefully.

The interrupted error means a query was cancelled before completion.

Understanding the Error

SQLITE_INTERRUPT: interrupted

Something called sqlite3_interrupt() on the database connection, or a progress callback returned non-zero.

Common Causes

1. User Cancelled Operation

User clicked "Cancel" on a long-running query.

2. Timeout

Query exceeded a time limit:

JAVASCRIPT
// Some libraries support timeout
const db = new Database('mydb.db');
db.pragma('busy_timeout = 5000');  // 5 second timeout

3. Progress Callback

A progress handler decided to stop:

JAVASCRIPT
let cancelled = false;

db.function('progress_handler', () => {
  if (cancelled) return 1;  // Stop query
  return 0;  // Continue
});

// User clicks cancel
cancelButton.onclick = () => { cancelled = true; };

4. Signal Handler

Application received SIGINT or similar.

How to Fix It

Solution 1: Handle Gracefully

JAVASCRIPT
try {
  const results = db.prepare('SELECT * FROM huge_table').all();
} catch (err) {
  if (err.code === 'SQLITE_INTERRUPT') {
    console.log('Query was cancelled');
    // Show user-friendly message
    showMessage('Operation cancelled');
  } else {
    throw err;
  }
}

Solution 2: Implement Proper Cancellation

JAVASCRIPT
class CancellableQuery {
  constructor(db) {
    this.db = db;
    this.cancelled = false;
  }

  cancel() {
    this.cancelled = true;
  }

  run(sql, params) {
    // Set up progress handler
    let steps = 0;
    this.db.function('progress_handler', () => {
      if (this.cancelled) return 1;
      steps++;
      if (steps % 1000 === 0) {
        console.log(`Progress: ${steps} steps`);
      }
      return 0;
    });

    try {
      return this.db.prepare(sql).all(params);
    } finally {
      this.cancelled = false;
    }
  }
}

Solution 3: Use Timeout Wrapper

JAVASCRIPT
function queryWithTimeout(db, sql, params, timeoutMs) {
  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      // Interrupt the query
      db.interrupt();
    }, timeoutMs);

    try {
      const result = db.prepare(sql).all(params);
      clearTimeout(timeout);
      resolve(result);
    } catch (err) {
      clearTimeout(timeout);
      reject(err);
    }
  });
}

Solution 4: Batch Long Operations

JAVASCRIPT
// Instead of one huge query, batch it
async function processAllRows(db, batchSize = 1000) {
  let offset = 0;
  const results = [];

  while (true) {
    if (cancelled) {
      throw new Error('Operation cancelled by user');
    }

    const batch = db.prepare(`
      SELECT * FROM huge_table LIMIT ? OFFSET ?
    `).all(batchSize, offset);

    if (batch.length === 0) break;

    results.push(...batch);
    offset += batchSize;

    // Allow UI to update
    await new Promise(r => setTimeout(r, 0));
  }

  return results;
}

Best Practices

  1. Handle SQLITE_INTERRUPT in error handling
  2. Show progress for long operations
  3. Allow cancellation for user-facing queries
  4. Set reasonable timeouts to prevent runaway queries
  5. Batch large operations for responsiveness