Skip to content

Commit

Permalink
Adjust the DB check error message (#1558)
Browse files Browse the repository at this point in the history
  • Loading branch information
infomiho authored Nov 9, 2023
1 parent 96ea796 commit 62aa2b7
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 13 deletions.
1 change: 1 addition & 0 deletions waspc/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ app todoApp {
### 🐞 Bug fixes / 🔧 small improvements
- Changed the minimum number of machines that a server app is using when deployed to Fly.io from 0 to 1. This prevents the server app from shutting down when there are no requests to it. There might be some other work that the server is doing e.g. running periodic Jobs or sending e-mails, so we want to make sure that the server is always running.
- Fixes a bug where copying of migrations dir failed due to a missing `migrations` dir.
- Fixes a regression where a missing DB on the DB server would prevent project from running. Now, Wasp will tolerate the missing DB error and rely on Prisma to create the DB for you (like before).


## 0.11.7
Expand Down
5 changes: 3 additions & 2 deletions waspc/cli/src/Wasp/Cli/Command/Require.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import qualified System.FilePath as FP
import Wasp.Cli.Command (CommandError (CommandError), Requirable (checkRequirement), require)
import Wasp.Cli.Common (WaspProjectDir)
import qualified Wasp.Cli.Common as Cli.Common
import Wasp.Generator.DbGenerator.Operations (isDbRunning)
import Wasp.Generator.DbGenerator.Operations (isDbConnectionPossible, testDbConnection)

data DbConnectionEstablished = DbConnectionEstablished deriving (Typeable)

Expand All @@ -49,7 +49,8 @@ instance Requirable DbConnectionEstablished where
-- call to 'require' will not result in an infinite loop.
InWaspProject waspProjectDir <- require
let outDir = waspProjectDir SP.</> Cli.Common.dotWaspDirInWaspProjectDir SP.</> Cli.Common.generatedCodeDirInDotWaspDir
dbIsRunning <- liftIO $ isDbRunning outDir
dbIsRunning <- liftIO $ isDbConnectionPossible <$> testDbConnection outDir

if dbIsRunning
then return DbConnectionEstablished
else throwError noDbError
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ CREATE TABLE "User" (
"id" SERIAL NOT NULL,
"username" TEXT NOT NULL,
"password" TEXT NOT NULL,
"address" TEXT,

CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
Expand Down
7 changes: 7 additions & 0 deletions waspc/examples/crud-testing/src/client/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vite";

export default defineConfig({
server: {
open: false
}
})
47 changes: 39 additions & 8 deletions waspc/src/Wasp/Generator/DbGenerator/Operations.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module Wasp.Generator.DbGenerator.Operations
areAllMigrationsAppliedToDb,
dbReset,
dbSeed,
isDbRunning,
testDbConnection,
isDbConnectionPossible,
prismaErrorContainsDbNotCreatedError,
)
where

Expand All @@ -17,10 +19,12 @@ import Control.Monad (when)
import Control.Monad.Catch (catch)
import Control.Monad.Extra (whenM)
import Data.Either (isRight)
import qualified Data.Text as T
import qualified Path as P
import StrongPath (Abs, Dir, File, Path', Rel, (</>))
import qualified StrongPath as SP
import System.Exit (ExitCode (..))
import qualified Text.Regex.TDFA as TR
import Wasp.Generator.Common (ProjectRootDir)
import Wasp.Generator.DbGenerator.Common
( DbSchemaChecksumFile,
Expand All @@ -38,13 +42,23 @@ import Wasp.Generator.DbGenerator.Common
import qualified Wasp.Generator.DbGenerator.Jobs as DbJobs
import Wasp.Generator.FileDraft.WriteableMonad (WriteableMonad (copyDirectoryRecursive, doesDirectoryExist))
import qualified Wasp.Generator.Job as J
import Wasp.Generator.Job.IO (printJobMsgsUntilExitReceived, readJobMessagesAndPrintThemPrefixed)
import Wasp.Generator.Job.IO
( collectJobTextOutputUntilExitReceived,
printJobMsgsUntilExitReceived,
readJobMessagesAndPrintThemPrefixed,
)
import qualified Wasp.Generator.WriteFileDrafts as Generator.WriteFileDrafts
import Wasp.Project.Db.Migrations (DbMigrationsDir)
import Wasp.Util (checksumFromFilePath, hexToString)
import Wasp.Util.IO (deleteFileIfExists, doesFileExist)
import qualified Wasp.Util.IO as IOUtil

data DbConnectionTestResult
= DbConnectionSuccess
| DbNotCreated
| DbConnectionFailure
deriving (Eq)

-- | Migrates in the generated project context and then copies the migrations dir back
-- up to the wasp project dir to ensure they remain in sync.
migrateDevAndCopyToSource :: Path' Abs (Dir DbMigrationsDir) -> Path' Abs (Dir ProjectRootDir) -> MigrateArgs -> IO (Either String ())
Expand Down Expand Up @@ -143,15 +157,32 @@ dbSeed genProjectDir seedName = do
ExitSuccess -> Right ()
ExitFailure c -> Left $ "Failed with exit code " <> show c

isDbRunning ::
testDbConnection ::
Path' Abs (Dir ProjectRootDir) ->
IO Bool
isDbRunning genProjectDir = do
IO DbConnectionTestResult
testDbConnection genProjectDir = do
chan <- newChan
exitCode <- DbJobs.dbExecuteTest genProjectDir chan
-- NOTE: We only care if the command succeeds or fails, so we don't look at
-- the exit code or stdout/stderr for the process.
return $ exitCode == ExitSuccess

case exitCode of
ExitSuccess -> return DbConnectionSuccess
ExitFailure _ -> do
outputLines <- collectJobTextOutputUntilExitReceived chan
let databaseNotCreated = any prismaErrorContainsDbNotCreatedError outputLines

return $
if databaseNotCreated
then DbNotCreated
else DbConnectionFailure

-- Prisma error code for "Database not created" is P1003.
prismaErrorContainsDbNotCreatedError :: T.Text -> Bool
prismaErrorContainsDbNotCreatedError text = text TR.=~ ("\\bP1003\\b" :: String)

isDbConnectionPossible :: DbConnectionTestResult -> Bool
isDbConnectionPossible DbConnectionSuccess = True
isDbConnectionPossible DbNotCreated = True
isDbConnectionPossible _ = False

generatePrismaClients :: Path' Abs (Dir ProjectRootDir) -> IO (Either String ())
generatePrismaClients projectRootDir = do
Expand Down
11 changes: 11 additions & 0 deletions waspc/src/Wasp/Generator/Job/IO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ module Wasp.Generator.Job.IO
( readJobMessagesAndPrintThemPrefixed,
printJobMessage,
printJobMsgsUntilExitReceived,
collectJobTextOutputUntilExitReceived,
)
where

import Control.Concurrent (Chan, readChan)
import Control.Monad.IO.Class (liftIO)
import Data.Text (Text)
import qualified Data.Text.IO as T.IO
import System.IO (hFlush)
import qualified Wasp.Generator.Job as J
Expand All @@ -29,6 +31,15 @@ readJobMessagesAndPrintThemPrefixed chan = runPrefixedWriter go
J.JobOutput {} -> printJobMessagePrefixed jobMsg >> go
J.JobExit {} -> return ()

collectJobTextOutputUntilExitReceived :: Chan J.JobMessage -> IO [Text]
collectJobTextOutputUntilExitReceived = go []
where
go jobTextOutput chan = do
jobMsg <- readChan chan
case J._data jobMsg of
J.JobExit {} -> return jobTextOutput
J.JobOutput text _ -> go (text : jobTextOutput) chan

printJobMessage :: J.JobMessage -> IO ()
printJobMessage jobMsg = do
let outHandle = getJobMessageOutHandle jobMsg
Expand Down
20 changes: 19 additions & 1 deletion waspc/test/Generator/DbGeneratorTest.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
module Generator.DbGeneratorTest where

import Test.Tasty.Hspec (Spec, it, shouldBe)
import qualified Data.Text as T
import Test.Tasty.Hspec (Spec, describe, it, shouldBe)
import Wasp.Generator.DbGenerator.Common
( MigrateArgs (..),
defaultMigrateArgs,
)
import Wasp.Generator.DbGenerator.Jobs (asPrismaCliArgs)
import Wasp.Generator.DbGenerator.Operations (prismaErrorContainsDbNotCreatedError)

spec_Jobs :: Spec
spec_Jobs =
Expand All @@ -19,3 +21,19 @@ spec_Jobs =
`shouldBe` ["--name", "something else longer"]
asPrismaCliArgs (MigrateArgs {_migrationName = Just "something", _isCreateOnlyMigration = True})
`shouldBe` ["--create-only", "--name", "something"]

spec_DbConnectionTest :: Spec
spec_DbConnectionTest =
describe "prismaErrorContainsDbNotCreatedError" $ do
it "should not match DB server not available error" $ do
prismaErrorContainsDbNotCreatedError
(T.pack "Error: P1001\n\nCan't reach database server at `localhost`:`5432`\n\nPlease make sure your database server is running at `localhost`:`5432`.")
`shouldBe` False
it "should not match similar error codes" $ do
prismaErrorContainsDbNotCreatedError
(T.pack "Error: P10033\n\nMade up error code")
`shouldBe` False
it "should match the DB not created error code" $ do
prismaErrorContainsDbNotCreatedError
(T.pack "Error: P1003\n\nDatabase `x` does not exist on the database server at `localhost:5432`.")
`shouldBe` True

0 comments on commit 62aa2b7

Please sign in to comment.