Skip to content

fix: WPB-22188 Fail fast on no DB connection#68

Merged
MarianKijewski merged 4 commits intomainfrom
fix/WPB-22188_Fail_fast_on_no_DB_connection
May 8, 2026
Merged

fix: WPB-22188 Fail fast on no DB connection#68
MarianKijewski merged 4 commits intomainfrom
fix/WPB-22188_Fail_fast_on_no_DB_connection

Conversation

@MarianKijewski
Copy link
Copy Markdown
Collaborator


PR Submission Checklist for internal contributors

  • The PR Title

    • conforms to the style of semantic commits messages¹ supported in Wire's Github Workflow²
    • contains a reference JIRA issue number like SQPIT-764
    • answers the question: If merged, this PR will: ... ³
  • The PR Description

    • is free of optional paragraphs and you have filled the relevant parts to the best of your ability

What's new in this PR?

Issues

The program execution continued despite no database connection which makes it unusable.

Solutions

Throw on connection failure.

Testing

Test Coverage

  • I have added automated test to this contribution

How to Test

Run the app without running database. The program should terminate with clear error.

Notes

I didn't implement retry mechanism as this can be done at container level if necessary.


References
  1. https://sparkbox.com/foundry/semantic_commit_messages
  2. https://github.com/wireapp/.github#usage
  3. E.g. feat(conversation-list): Sort conversations by most emojis in the title #SQPIT-764.

@MarianKijewski MarianKijewski requested a review from a team as a code owner May 7, 2026 16:31
@claude
Copy link
Copy Markdown

claude Bot commented May 7, 2026

Code review

Thanks for the fix — the intent (fail-fast on missing DB) is right and the production change is small and focused. A few items worth addressing on the test side, plus a couple of small suggestions.

src/main/kotlin/com/wire/apps/polls/setup/KtorInstallation.kt

  • error(\"Unable to connect to the database\") is idiomatic Kotlin and gets the job done (it throws IllegalStateException). Two minor nits to consider:
    • Consider logging at error level just before throwing, so operators get the same clear log line they had before in addition to the stack trace. Right now the only context downstream is the exception message.
    • A more domain-specific exception (e.g. DatabaseConnectionException) would communicate intent better and let callers/tests assert on the type unambiguously, but IllegalStateException is acceptable for fail-fast init.
  • Agree with the PR description that retry belongs at the orchestration layer (k8s / docker-compose restart), so leaving that out is fine.

src/test/kotlin/com/wire/apps/polls/setup/SetupTest.kt

A few issues here, in roughly priority order:

  1. Missing package declaration. Every other file under src/test/kotlin declares its package (e.g. package com.wire.apps.polls.services in PollServiceTest.kt). This new file has none, which puts SetupTest in the root/default package — inconsistent with the rest of the suite and likely to trip ktlint/style checks. Add:

    package com.wire.apps.polls.setup
  2. Test likely passes for the wrong reason. connectDatabase() does:

    val dbConfig by closestDI().instance<DatabaseConfiguration>()
    DatabaseSetup.connect(dbConfig)
    if (DatabaseSetup.isConnected()) { ... } else { error(...) }

    dbConfig is a lazy delegate — accessing it triggers a Kodein lookup. testApplication { } does not install Kodein, so when DatabaseSetup.connect(dbConfig) is evaluated, reading dbConfig throws (Kodein's not-found / DI-missing error, which surfaces as some flavor of IllegalStateException). The test would still satisfy assertFailsWith<IllegalStateException>, but the isConnected() == false branch is never reached — so the test doesn't actually exercise the new fail-fast code path.

    To genuinely cover the change, install Kodein inside testApplication and bind a stub DatabaseConfiguration, e.g.:

    testApplication {
        application {
            di {
                bind<DatabaseConfiguration>() with singleton {
                    DatabaseConfiguration(url = \"\", userName = \"\", password = \"\")
                }
            }
        }
        mockkObject(DatabaseSetup)
        every { DatabaseSetup.isConnected() } returns false
        // ...
    }

    You could also assert on the exception message (assertFailsWith<IllegalStateException> { ... }.message contains "Unable to connect") to make the test specific to the new branch rather than any IllegalStateException.

  3. No unmockkObject / unmockkAll cleanup. mockkObject(DatabaseSetup) registers a global static mock for the duration of the JVM; without cleanup it leaks into any other test that touches DatabaseSetup in the same run. Add an @AfterEach (or try { ... } finally { unmockkObject(DatabaseSetup) }) to clean up.

  4. testApplication may be heavier than needed. Since connectDatabase() only needs an Application receiver, and you're mocking DatabaseSetup anyway, you could likely just construct a lightweight test application without spinning up the full ktor test host — but testApplication is acceptable if you prefer the consistency.

build.gradle.kts

  • Adding ktor-server-test-host as testImplementation is fine. Pinning it to ktorVersion keeps versions aligned — good.

Summary

Production change LGTM. Please:

  • add the missing package declaration,
  • ensure the test actually drives the isConnected() == false branch (install Kodein with a stub DatabaseConfiguration, and ideally assert on the exception message),
  • add unmockkObject/unmockkAll cleanup.

@MarianKijewski MarianKijewski merged commit 0b28e0d into main May 8, 2026
4 checks passed
@MarianKijewski MarianKijewski deleted the fix/WPB-22188_Fail_fast_on_no_DB_connection branch May 8, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants