Skip to content

Conversation

DanielBiegler
Copy link
Contributor

@DanielBiegler DanielBiegler commented Jul 3, 2025

While working on something else I found this logic bug, copying over from here so that this PR stays self contained:

In #3222 I am trying to introduce a new strategy which is needed during the intitialization phase of Vendure but due to the order of nest module life cycle hooks, Vendure currently fails to get injectables during initialization.

  1. I did include the strategy in the config modules private getInjectableStrategies() - This is important because the strategies get initialized in the above initInjectableStrategies() which gets called in the config modules onApplicationBootstrap hook. This is correct, but keyword being this specific lifecycle hook.
  2. The InitializerService which is responsible for calling Vendure-essential initializations sequentially, hooks into onModuleInit which runs BEFORE onApplicationBootstrap-hooks i.e. before the config module.
  3. So after nest boots up and starts calling all the needed hooked in modules, InitializerService starts initializing multiple things like channels, roles, admins, etc. BEFORE the config module was able to call initInjectableStrategies() - which only gets called after, at application bootstrap.
  4. This results in strategies not having their init(injector: Injector) function called in time, making essential dependencies like TransactionalConnection and other services undefined.

I quickly skimmed through all the initializer functions and this bug has been hiding until today because none of the essential services used injectable strategies in their initialization. As soon as Vendure introduces some strategy, thats needed when initializing, this bug will occur.

Description

For testing purposes I swapped the hooks so that config module injects before initializerservice runs.

Breaking changes

Since this touches the very core of Vendure we must check thoroughly - are there further things to consider? I think nest calls the hooks concurrently through promise.all so a good solution must make sure the strategies and operations are always initialized before initialization-service runs, hence me swapping their hooks. initInjectableStrategies() must run after all the plugins had the chance to alter the config.

Checklist

📌 Always:

  • I have set a clear title
  • My PR is small and contains a single feature
  • I have checked my own PR

👍 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

Summary by CodeRabbit

  • Refactor
    • Adjusted the timing of certain initialization processes to improve application startup behavior. No user-facing changes or impact on functionality.

Copy link

vercel bot commented Jul 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview Jul 3, 2025 11:53pm

Copy link
Contributor

coderabbitai bot commented Jul 3, 2025

Walkthrough

The updates shift lifecycle hook implementations between ConfigModule and InitializerService. ConfigModule now uses OnModuleInit instead of OnApplicationBootstrap, renaming its hook method accordingly. Conversely, InitializerService now implements OnApplicationBootstrap instead of OnModuleInit, with its initialization logic moved to the corresponding hook.

Changes

File(s) Change Summary
packages/core/src/config/config.module.ts Changed ConfigModule to implement OnModuleInit instead of OnApplicationBootstrap; renamed lifecycle hook method.
packages/core/src/service/initializer.service.ts Changed InitializerService to implement OnApplicationBootstrap instead of OnModuleInit; renamed lifecycle hook method.

Sequence Diagram(s)

sequenceDiagram
    participant NestJS
    participant ConfigModule
    participant InitializerService

    %% Module initialization phase
    NestJS->>ConfigModule: onModuleInit()
    ConfigModule->>ConfigModule: Initialize strategies and operations

    %% Application bootstrap phase
    NestJS->>InitializerService: onApplicationBootstrap()
    InitializerService->>InitializerService: Await DB schema, initialize services, publish event
Loading

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-04T00_10_54_170Z-debug-0.log


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

sonarqubecloud bot commented Jul 3, 2025

@DanielBiegler DanielBiegler marked this pull request as ready for review July 4, 2025 00:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/core/src/service/initializer.service.ts (1)

45-45: Consider updating the comment reference.

The comment still references "onModuleInit" but the context is about lifecycle hooks in general, so the meaning is still clear. However, you may want to update it for consistency.

-        // Nest's "onModuleInit" lifecycle hook within each individual service class?
+        // Nest's lifecycle hooks within each individual service class?
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40f1ca3 and d3bdc6e.

📒 Files selected for processing (2)
  • packages/core/src/config/config.module.ts (2 hunks)
  • packages/core/src/service/initializer.service.ts (3 hunks)
🔇 Additional comments (6)
packages/core/src/config/config.module.ts (3)

1-1: LGTM: Import updated correctly for lifecycle hook change.

The import change from OnApplicationBootstrap to OnModuleInit is consistent with the lifecycle hook swap.


15-15: LGTM: Class interface updated correctly.

The class now implements OnModuleInit instead of OnApplicationBootstrap, which moves the initialization earlier in the lifecycle as intended.


21-24: LGTM: Method renamed and timing adjusted correctly.

The method is now onModuleInit() instead of onApplicationBootstrap(), which ensures injectable strategies are initialized earlier in the lifecycle. This addresses the core issue where strategies need to be available before InitializerService runs.

packages/core/src/service/initializer.service.ts (3)

1-1: LGTM: Import updated correctly for lifecycle hook change.

The import change from OnModuleInit to OnApplicationBootstrap is consistent with the lifecycle hook swap.


27-27: LGTM: Class interface updated correctly.

The class now implements OnApplicationBootstrap instead of OnModuleInit, which moves the initialization later in the lifecycle as intended. This ensures injectable strategies are available before this service runs.


42-60: LGTM: Method renamed and timing adjusted correctly.

The method is now onApplicationBootstrap() instead of onModuleInit(), which ensures this service runs after the ConfigModule has initialized injectable strategies. This fixes the core timing issue described in the PR objectives.

@michaelbromley
Copy link
Member

Hi Daniel, thanks for taking some time to look into this.

This is indeed quite a consequential change, and I'm also a bit nervous about the implications on people's plugins that might implicitly rely on the current order of execution.

I'm not yet sure how best to handle this if it turns out we need to change it.

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