04: background jobs - #3
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (8)
Tip You can disable sequence diagrams in the walkthrough.Disable the ✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Docstrings generation was requested by @AndyY-Q. * #3 (comment) The following files were modified: * `src/app/layout.tsx`
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
src/app/api/inngest/route.ts (1)
6-6: Fix misleading comment.The comment states "serves zero functions" but the code actually serves the
helloWorldfunction.-// Create an API that serves zero functions +// Create an API that serves Inngest functionssrc/inngest/client.ts (1)
4-4: Consider environment-specific client configuration.The client ID is hardcoded. For production deployments, consider making this configurable via environment variables to support different environments (dev, staging, prod).
-export const inngest = new Inngest({ id: "anacotte-same" }); +export const inngest = new Inngest({ + id: process.env.INNGEST_APP_ID || "anacotte-same" +});
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (8)
package.json(1 hunks)src/app/api/inngest/route.ts(1 hunks)src/app/client.tsx(0 hunks)src/app/layout.tsx(2 hunks)src/app/page.tsx(1 hunks)src/inngest/client.ts(1 hunks)src/inngest/functions.ts(1 hunks)src/trpc/routers/_app.ts(1 hunks)
💤 Files with no reviewable changes (1)
- src/app/client.tsx
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/app/page.tsx (2)
src/trpc/server.tsx (1)
trpc(10-14)src/components/ui/button.tsx (1)
Button(59-59)
src/trpc/routers/_app.ts (2)
src/trpc/init.ts (2)
createTRPCRouter(21-21)baseProcedure(23-23)src/inngest/client.ts (1)
inngest(4-4)
src/inngest/functions.ts (1)
src/inngest/client.ts (1)
inngest(4-4)
src/app/api/inngest/route.ts (2)
src/inngest/client.ts (1)
inngest(4-4)src/inngest/functions.ts (1)
helloWorld(3-15)
🔇 Additional comments (6)
src/app/layout.tsx (2)
5-5: LGTM! Clean integration of toast notifications.The import is correctly placed and the sonner library is a well-established choice for toast notifications.
33-33: LGTM! Proper placement of the Toaster component.The
<Toaster />is correctly positioned inside the body but outside the main content, allowing toasts to appear over all application content.src/app/api/inngest/route.ts (1)
7-12: LGTM! Standard Inngest API setup.The
servefunction configuration correctly exports the HTTP handlers and registers thehelloWorldfunction. This follows Inngest's recommended pattern for Next.js integration.package.json (1)
50-50: Inngest dependency is up-to-date and has no known vulnerabilities
- Confirmed via npm registry that the latest
inngestrelease is 3.40.1- No direct security issues reported for v3.40.1 in public vulnerability databases
No changes required. You can proceed with this addition.
src/trpc/routers/_app.ts (1)
3-3: LGTM! Clean import of the Inngest client.The import correctly references the client instance created in
src/inngest/client.ts.src/app/page.tsx (1)
11-27: Well-structured client-side mutation implementation.The component transformation from server-side to client-side is well-implemented with proper error handling, loading states, and user feedback through toast notifications.
| invoke: baseProcedure | ||
| .input(z.object({ | ||
| text: z.string(), | ||
| })) | ||
| .mutation(async ({ input }) => { | ||
| await inngest.send({ | ||
| name: "test/hello.world", | ||
| data: { | ||
| email: input.text, | ||
| }, | ||
| }); | ||
| return {ok: "Success",}; | ||
| }), |
There was a problem hiding this comment.
Add error handling and improve field naming.
The invoke mutation has several issues:
- Missing error handling: The
inngest.sendcall could fail and throw an unhandled exception - Confusing field mapping:
input.textis mapped toemailin the event data, which is misleading - No validation: The mutation returns success regardless of whether the event was actually processed
invoke: baseProcedure
.input(z.object({
- text: z.string(),
+ email: z.string(),
}))
.mutation(async ({ input }) => {
- await inngest.send({
- name: "test/hello.world",
- data: {
- email: input.text,
- },
- });
- return {ok: "Success",};
+ try {
+ await inngest.send({
+ name: "test/hello.world",
+ data: {
+ email: input.email,
+ },
+ });
+ return { ok: "Success" };
+ } catch (error) {
+ throw new Error("Failed to send background job event");
+ }
}),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| invoke: baseProcedure | |
| .input(z.object({ | |
| text: z.string(), | |
| })) | |
| .mutation(async ({ input }) => { | |
| await inngest.send({ | |
| name: "test/hello.world", | |
| data: { | |
| email: input.text, | |
| }, | |
| }); | |
| return {ok: "Success",}; | |
| }), | |
| invoke: baseProcedure | |
| .input(z.object({ | |
| email: z.string(), | |
| })) | |
| .mutation(async ({ input }) => { | |
| try { | |
| await inngest.send({ | |
| name: "test/hello.world", | |
| data: { | |
| email: input.email, | |
| }, | |
| }); | |
| return { ok: "Success" }; | |
| } catch (error) { | |
| throw new Error("Failed to send background job event"); | |
| } | |
| }), |
🤖 Prompt for AI Agents
In src/trpc/routers/_app.ts around lines 5 to 17, the invoke mutation lacks
error handling, uses a confusing field name, and does not validate event
processing. To fix this, rename the input field from text to email for clarity,
wrap the inngest.send call in a try-catch block to handle potential errors, and
return a success response only if the event is sent without exceptions;
otherwise, return an error response indicating failure.
|
|
||
| //Imagine this is a sunmmary step | ||
| await step.sleep("wait-a-moment", "5s"); | ||
| return { message: `Hello ${event.data.email}!` }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add type safety for event data access.
The function accesses event.data.email without type validation, which could lead to runtime errors if the event data structure doesn't match expectations.
Consider adding type safety by defining an event type interface:
+interface HelloWorldEvent {
+ email: string;
+}
+
export const helloWorld = inngest.createFunction(
{ id: "hello-world" },
- { event: "test/hello.world" },
+ { event: "test/hello.world" },
- async ({ event, step }) => {
+ async ({ event, step }: { event: { data: HelloWorldEvent }, step: any }) => {🤖 Prompt for AI Agents
In src/inngest/functions.ts at line 13, the code accesses event.data.email
without type safety, risking runtime errors if the event structure is
unexpected. Define a TypeScript interface for the event data specifying the
expected shape, including the email property, and use this interface to type the
event parameter. This ensures compile-time type checking and safer access to
event data properties.
| await step.sleep("wait-a-moment", "10s"); | ||
|
|
||
| //Imagine this is a sunmmary step | ||
| await step.sleep("wait-a-moment", "5s"); |
There was a problem hiding this comment.
Fix duplicate step labels and typo in comment.
Two issues identified:
- Both
step.sleepcalls use the same label "wait-a-moment", which could cause conflicts in the Inngest workflow execution - Typo in line 11 comment: "sunmmary" should be "summary"
Apply this diff to fix both issues:
- //Imagine this is a transcript step
- await step.sleep("wait-a-moment", "10s");
-
- //Imagine this is a sunmmary step
- await step.sleep("wait-a-moment", "5s");
+ //Imagine this is a transcript step
+ await step.sleep("transcript-step", "10s");
+
+ //Imagine this is a summary step
+ await step.sleep("summary-step", "5s");Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/inngest/functions.ts lines 9 to 12, fix the duplicate step labels by
giving each step.sleep call a unique label to avoid conflicts in the workflow
execution. Also, correct the typo in the comment on line 11 by changing
"sunmmary" to "summary".
| ) | ||
| } | ||
| <div className="p-4 max-w-7xl mx-auto"> | ||
| <Button disabled={invoke.isPending} onClick={() => invoke.mutate({text: "Hello!"})}> |
There was a problem hiding this comment.
Fix payload mismatch between mutation and Inngest function.
The mutation is sending {text: "Hello!"} but the Inngest function in src/inngest/functions.ts expects the email field in event.data.email.
Apply this diff to align the payload with the Inngest function expectations:
- <Button disabled={invoke.isPending} onClick={() => invoke.mutate({text: "Hello!"})}>
+ <Button disabled={invoke.isPending} onClick={() => invoke.mutate({email: "Hello!"})}>Alternatively, if the intention is to send an email address, consider using a more appropriate value:
- <Button disabled={invoke.isPending} onClick={() => invoke.mutate({text: "Hello!"})}>
+ <Button disabled={invoke.isPending} onClick={() => invoke.mutate({email: "user@example.com"})}>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Button disabled={invoke.isPending} onClick={() => invoke.mutate({text: "Hello!"})}> | |
| <Button disabled={invoke.isPending} onClick={() => invoke.mutate({email: "Hello!"})}> |
🤖 Prompt for AI Agents
In src/app/page.tsx at line 22, the mutation payload sends {text: "Hello!"} but
the Inngest function expects an email field in event.data.email. Update the
payload in the invoke.mutate call to send {email:
"appropriate_email@example.com"} instead of {text: "Hello!"} to match the
expected structure.
|
Note Generated docstrings for this pull request at #4 |
Summary by CodeRabbit
New Features
Other Changes