refactor: optimized error handling (#2020)

* Update output.yaml

* Update default-pipeline-config.json

* Update chat.py

* Add files via upload

* Update chat.py

* Update default-pipeline-config.json

* Update output.yaml

* Update constants.py

* feat: update logic

* fix: update required database version to 21

---------

Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
Typer_Body
2026-03-10 22:01:23 +08:00
committed by GitHub
parent 13cb0aa9be
commit 0541b05966
5 changed files with 119 additions and 10 deletions

View File

@@ -0,0 +1,74 @@
from .. import migration
import sqlalchemy
import json
@migration.migration_class(21)
class DBMigrateMergeExceptionHandling(migration.DBMigration):
"""Merge hide-exception and block-failed-request-output into a single exception-handling select option,
and add failure-hint field.
Conversion logic:
- block-failed-request-output=true -> exception-handling: hide
- hide-exception=true -> exception-handling: show-hint
- hide-exception=false -> exception-handling: show-error
"""
async def upgrade(self):
"""Upgrade"""
result = await self.ap.persistence_mgr.execute_async(
sqlalchemy.text('SELECT uuid, config FROM legacy_pipelines')
)
pipelines = result.fetchall()
current_version = self.ap.ver_mgr.get_current_version()
for pipeline_row in pipelines:
uuid = pipeline_row[0]
config = json.loads(pipeline_row[1]) if isinstance(pipeline_row[1], str) else pipeline_row[1]
if 'output' not in config:
config['output'] = {}
if 'misc' not in config['output']:
config['output']['misc'] = {}
misc = config['output']['misc']
# Determine new exception-handling value from legacy fields
hide_exception = misc.get('hide-exception', True)
block_failed = misc.get('block-failed-request-output', False)
if block_failed:
exception_handling = 'hide'
elif hide_exception:
exception_handling = 'show-hint'
else:
exception_handling = 'show-error'
misc['exception-handling'] = exception_handling
# Add failure-hint with default value
misc['failure-hint'] = 'Request failed.'
# Remove legacy fields
misc.pop('hide-exception', None)
if self.ap.persistence_mgr.db.name == 'postgresql':
await self.ap.persistence_mgr.execute_async(
sqlalchemy.text(
'UPDATE legacy_pipelines SET config = :config::jsonb, for_version = :for_version WHERE uuid = :uuid'
),
{'config': json.dumps(config), 'for_version': current_version, 'uuid': uuid},
)
else:
await self.ap.persistence_mgr.execute_async(
sqlalchemy.text(
'UPDATE legacy_pipelines SET config = :config, for_version = :for_version WHERE uuid = :uuid'
),
{'config': json.dumps(config), 'for_version': current_version, 'uuid': uuid},
)
async def downgrade(self):
"""Downgrade"""
pass

View File

@@ -149,12 +149,19 @@ class ChatMessageHandler(handler.MessageHandler):
self.ap.logger.error(f'Conversation({query.query_id}) Request Failed: {error_info}')
traceback.print_exc()
hide_exception_info = query.pipeline_config['output']['misc']['hide-exception']
exception_handling = query.pipeline_config['output']['misc'].get('exception-handling', 'show-hint')
if exception_handling == 'show-error':
user_notice = f'{e}'
elif exception_handling == 'show-hint':
user_notice = query.pipeline_config['output']['misc'].get('failure-hint', 'Request failed.')
else: # hide
user_notice = None
yield entities.StageProcessResult(
result_type=entities.ResultType.INTERRUPT,
new_query=query,
user_notice='请求失败' if hide_exception_info else f'{e}',
user_notice=user_notice,
error_notice=f'{e}',
debug_notice=traceback.format_exc(),
)

View File

@@ -2,7 +2,7 @@ import langbot
semantic_version = f'v{langbot.__version__}'
required_database_version = 20
required_database_version = 21
"""Tag the version of the database schema, used to check if the database needs to be migrated"""
debug_mode = False

View File

@@ -95,11 +95,12 @@
"max": 0
},
"misc": {
"hide-exception": true,
"exception-handling": "show-hint",
"failure-hint": "Request failed.",
"at-sender": true,
"quote-origin": true,
"track-function-calls": false,
"remove-think": false
}
}
}
}

View File

@@ -78,13 +78,39 @@ stages:
en_US: Misc
zh_Hans: 杂项
config:
- name: hide-exception
- name: exception-handling
label:
en_US: Hide Exception
zh_Hans: 不输出异常信息给用户
type: boolean
en_US: Exception Handling Strategy
zh_Hans: 异常处理策略
description:
en_US: Controls how error messages are displayed to the user when an AI request fails
zh_Hans: 控制 AI 请求失败时向用户展示错误信息的方式
type: select
required: true
default: true
default: show-hint
options:
- name: show-error
label:
en_US: Show Full Error
zh_Hans: 显示完整报错信息
- name: show-hint
label:
en_US: Show Failure Hint
zh_Hans: 仅文字提示
- name: hide
label:
en_US: Hide All
zh_Hans: 不显示任何异常信息
- name: failure-hint
label:
en_US: Failure Hint Text
zh_Hans: 失败提示文本
description:
en_US: The text to display when a request fails. Only effective when Exception Handling Strategy is set to "Show Failure Hint"
zh_Hans: 请求失败时显示的提示文本,仅在异常处理策略设置为"仅文字提示"时生效
type: string
required: false
default: 'Request failed.'
- name: at-sender
label:
en_US: At Sender
@@ -119,3 +145,4 @@ stages:
type: boolean
required: true
default: false