-
Notifications
You must be signed in to change notification settings - Fork 10.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): Improve model sub-nodes error handling #11418
fix(core): Improve model sub-nodes error handling #11418
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On line 326 is another occurrence of context.functionality
-- can you check if that needs to change too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And same for packages/editor-ui/src/utils/expressions.ts
line 63.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fine as this is for another case, when nodes use "pairedItem" feature (e.g. referencing previous node's item value when the pairedItem connection was interrupted)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but you don't set context.functionality
anymore now? does that functionality break?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's being set in n8nLlmFailedAttemptHandler.ts
when we wrap the error into NodeApiError. For the paired item exceptions – nothing changes, I guess it's being set in WorkflowDataProxy.ts
and should not be affected by this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I see your point now. I found that setting context.functionality
to configuration-node
on NodeApiError does nothing, as it checks for the functionality on the exception object itself. Now I see that the checks are different for the configuration-node
functionality and pairedItem
. Good catch, thank you!
…in-the-sub-node-even-if # Conflicts: # packages/@n8n/nodes-langchain/nodes/llms/N8nLlmTracing.ts
Codecov ReportAttention: Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! thanks for addressing the issues with context.functionality
, and for adding the extra tests! 👍
n8n Run #7788
Run Properties:
|
Project |
n8n
|
Branch Review |
ai-298-errors-happen-in-the-root-node-not-in-the-sub-node-even-if
|
Run status |
Passed #7788
|
Run duration | 04m 22s |
Commit |
188f76131f: 🌳 🖥️ browsers:node18.12.0-chrome107 🤖 burivuhster 🗃️ e2e/*
|
Committer | Eugene Molodkin |
View all properties for this run ↗︎ |
Test results | |
---|---|
Failures |
0
|
Flaky |
1
|
Pending |
0
|
Skipped |
0
|
Passing |
461
|
View all changes introduced in this branch ↗︎ |
✅ All Cypress E2E specs passed |
Got released with |
Summary
Problem
The current error handling in LLM sub-nodes has two main issues:
Context
The error handling relies on custom exception classes (e.g.,
NodeOperationError
). However, there's no straightforward mechanism to wrap model exceptions before they propagate to the root node.Solution Approaches Explored
N8nLlmTracing
(callback handler passed to the LangChain model's contructor). UsinghandleLLMError
callback handler allows to add proper error info to the sub-node and fix the infinite running issue. But it can not be used for wrapping the exception for the root node.onFailedAttempt
callback can be provided during each model's LangChain class instantiation. It allows to intercept the retry logic built into LangChain, and re-throw the wrapped exceptions.Implementation
To use the second approach, the new helper function
makeN8nLlmFailedAttemptHandler
was implemented. It catches LLM errors, wrap them with our custom error classes, provides some default error handling logic (interrupt running if it does not make sense to retry for the specific error), and also allows to customize error handling for the specific cases (for example to use a custom error message for the OpenAI's insufficient quota error).Known issues
Couple of LangChain model classes do not use the
AsyncCaller
for their calls. It means, that the common retry logic built into LangChain does not work in such cases. TheonFailedAttempt
callback is not being called as well.Thus, the described error wrapping logic does not work yet for the following models:
LMChatOllama
LmChatAwsBedrock
LmChatGoogleVertex
Example 1. Insufficient quota error (OpenAI)
Before:
After:
Example 2. Empty prompt (Anthropic)
Before:
After:
Example 3. Nested sub-node error
Before:
After:
Example 4. Nested sub-node error
Before:
After:
Related Linear tickets, Github issues, and Community forum posts
Review / Merge checklist
release/backport
(if the PR is an urgent fix that needs to be backported)