diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+### 0.2.0.1
+
+- Fix: finalize prepared statements even when errors are encountered
+
 ### 0.2.0.0
 
 * Rework the API
diff --git a/sqlite-easy.cabal b/sqlite-easy.cabal
--- a/sqlite-easy.cabal
+++ b/sqlite-easy.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.4
 
 name: sqlite-easy
-version: 0.2.0.0
+version: 0.2.0.1
 synopsis: A primitive yet easy to use sqlite library.
 description: A primitive yet easy to use sqlite library built using sqlite-direct, resource-pool and migrant.
 author: Gil Mizrahi
diff --git a/src/Database/Sqlite/Easy.hs b/src/Database/Sqlite/Easy.hs
--- a/src/Database/Sqlite/Easy.hs
+++ b/src/Database/Sqlite/Easy.hs
@@ -58,12 +58,12 @@
 {- $connecting
 
 The easiest way to run some statements on the database is using the
-'withDb' function. 'withDb' uses continuation-passing style and expects
-a connection string (such as a file with flags or @:memory:@,
-see sqlite3 docs: <https://www.sqlite.org/c3ref/open.html>), and
-a function that will take the database handle and do things with it.
-It will open the connection to the database and call the function,
-passing the database handle to it.
+'withDb' function. 'withDb' expects a connection string
+(such as a file with flags or @:memory:@, see sqlite3 docs:
+<https://www.sqlite.org/c3ref/open.html>), and SQLite action(s),
+such as queries and statements.
+It will open the connection to the database and run the SQLite actions
+on that database.
 
 === Example
 
@@ -86,7 +86,7 @@
 We can use the 'createSqlitePool' function to create a @Pool 'Database'@
 and pass that around until you are ready to use the database.
 
-We can use 'withPool' like we did with 'withDb' but passing a 'Database'
+We can use 'withPool' like we did with 'withDb' but passing a @Pool Database@
 instead of a 'ConnectionString'.
 
 === Example
@@ -210,7 +210,7 @@
 
 {- $suggestions
 
-A suggestion for the architecture of your database interactions: use the handler pattern!
+A suggestion for the architecture of your database interactions: use the handle pattern!
 
 === 1. Create a type for your API
 
@@ -257,9 +257,9 @@
 
 and so on.
 
-=== 3. Use the handler from your application code
+=== 3. Use the handle from your application code
 
-When you start the application, run @mkDB@ and get a handler, and pass it around
+When you start the application, run @mkDB@ and get a handle, and pass it around
 (or use @ReaderT@). When you need to run a database command, call a field from @DB@:
 
 > -- A page for a specific post
diff --git a/src/Database/Sqlite/Easy/Internal.hs b/src/Database/Sqlite/Easy/Internal.hs
--- a/src/Database/Sqlite/Easy/Internal.hs
+++ b/src/Database/Sqlite/Easy/Internal.hs
@@ -61,16 +61,16 @@
 run :: SQL -> SQLite [[SQLData]]
 run (SQL stmt) = do
   db <- getDB
-  liftIO (prepare db stmt >>= fetchAll)
+  liftIO $ bracket (prepare db stmt) finalize fetchAll
 
 -- | Run a SQL statement with certain parameters on a database and fetch the results.
 runWith :: SQL -> [SQLData] -> SQLite [[SQLData]]
 runWith (SQL stmt) params = do
   db <- getDB
   liftIO $ do
-    preparedStmt <- prepare db stmt
-    bind preparedStmt params
-    fetchAll preparedStmt
+    bracket (prepare db stmt) finalize $ \preparedStmt -> do
+      bind preparedStmt params
+      fetchAll preparedStmt
 
 -- | Run a statement and fetch all of the data.
 fetchAll :: Statement -> IO [[SQLData]]
@@ -81,12 +81,19 @@
       row <- columns stmt
       rows <- fetchAll stmt
       pure (row : rows)
-    Done -> do
-      finalize stmt
+    Done ->
       pure []
 
 -- * Transaction
 
+-- | The type of actions to run on a SQLite database.
+--   In essence, it is almost the same as @Database -> IO a@.
+--
+--   'SQLite' actions can be created with the 'run' and 'runWith'
+--   functions, and can be composed using the type class instances.
+--
+--   'SQLite' actions can be run with the 'withDb', 'withDatabase',
+--   and 'withPool' functions.
 newtype SQLite a
   = SQLite
     { unSQLite :: SQLiteStuff -> IO a
diff --git a/test/SqliteEasySpec.hs b/test/SqliteEasySpec.hs
--- a/test/SqliteEasySpec.hs
+++ b/test/SqliteEasySpec.hs
@@ -3,9 +3,10 @@
 
 module SqliteEasySpec (spec) where
 
+import Data.List (isInfixOf)
 import Test.Hspec
 import Database.Sqlite.Easy
-import UnliftIO.Exception (try)
+import UnliftIO.Exception (try, catch, displayException, SomeException(..))
 
 spec :: Spec
 spec = do
@@ -27,6 +28,23 @@
       shouldBe
         result
         [[SQLInteger 1]]
+
+    it "sql injection" $ do
+      result <- withDb ":memory:" $ do
+        [] <- run "create table students(name text not null)"
+        [] <- runWith "insert into students values (?)" [SQLText "Robert'); DROP TABLE students;--"]
+        run "select * from students"
+      shouldBe
+        result
+        [[SQLText "Robert'); DROP TABLE students;--"]]
+
+    it "finalize prepared statement on error" $ do
+      shouldThrow
+        ( withDb ":memory:" $ do
+          [] <- run "create table test (id integer primary key autoincrement, val text unique)"
+          run "insert into test (val) values ('hello'), ('hello')"
+        )
+        (\(SomeException e) -> "constraint failed: test.val" `isInfixOf` displayException e)
 
   describe "transactions" $ do
     it "transaction is rolled back in case of error" $ do
