mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
Fix JSON serialization error for ModelMetaclass objects (#9812)
- Add robust serialize_for_json() function to handle non-serializable objects - Update server_error_response() to safely serialize exception data - Update get_json_result() with fallback error handling - Handles ModelMetaclass, functions, and other problematic objects - Maintains proper JSON response format instead of server crashes Fixes #9797 ### What problem does this PR solve? Currently, error responses and certain result objects may include types that are not JSON serializable (e.g., ModelMetaclass, functions). This causes server crashes instead of returning valid JSON responses. This PR introduces a robust serializer that converts unsupported types into string representations, ensuring the server always returns a valid JSON response. ### Type of change - [] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -56,6 +56,30 @@ from rag.utils.mcp_tool_call_conn import MCPToolCallSession, close_multiple_mcp_
|
|||||||
|
|
||||||
requests.models.complexjson.dumps = functools.partial(json.dumps, cls=CustomJSONEncoder)
|
requests.models.complexjson.dumps = functools.partial(json.dumps, cls=CustomJSONEncoder)
|
||||||
|
|
||||||
|
def serialize_for_json(obj):
|
||||||
|
"""
|
||||||
|
Recursively serialize objects to make them JSON serializable.
|
||||||
|
Handles ModelMetaclass and other non-serializable objects.
|
||||||
|
"""
|
||||||
|
if hasattr(obj, '__dict__'):
|
||||||
|
# For objects with __dict__, try to serialize their attributes
|
||||||
|
try:
|
||||||
|
return {key: serialize_for_json(value) for key, value in obj.__dict__.items()
|
||||||
|
if not key.startswith('_')}
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
return str(obj)
|
||||||
|
elif hasattr(obj, '__name__'):
|
||||||
|
# For classes and metaclasses, return their name
|
||||||
|
return f"<{obj.__module__}.{obj.__name__}>" if hasattr(obj, '__module__') else f"<{obj.__name__}>"
|
||||||
|
elif isinstance(obj, (list, tuple)):
|
||||||
|
return [serialize_for_json(item) for item in obj]
|
||||||
|
elif isinstance(obj, dict):
|
||||||
|
return {key: serialize_for_json(value) for key, value in obj.items()}
|
||||||
|
elif isinstance(obj, (str, int, float, bool)) or obj is None:
|
||||||
|
return obj
|
||||||
|
else:
|
||||||
|
# Fallback: convert to string representation
|
||||||
|
return str(obj)
|
||||||
|
|
||||||
def request(**kwargs):
|
def request(**kwargs):
|
||||||
sess = requests.Session()
|
sess = requests.Session()
|
||||||
@ -128,7 +152,11 @@ def server_error_response(e):
|
|||||||
except BaseException:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
if len(e.args) > 1:
|
if len(e.args) > 1:
|
||||||
return get_json_result(code=settings.RetCode.EXCEPTION_ERROR, message=repr(e.args[0]), data=e.args[1])
|
try:
|
||||||
|
serialized_data = serialize_for_json(e.args[1])
|
||||||
|
return get_json_result(code= settings.RetCode.EXCEPTION_ERROR, message=repr(e.args[0]), data=serialized_data)
|
||||||
|
except Exception:
|
||||||
|
return get_json_result(code=settings.RetCode.EXCEPTION_ERROR, message=repr(e.args[0]), data=None)
|
||||||
if repr(e).find("index_not_found_exception") >= 0:
|
if repr(e).find("index_not_found_exception") >= 0:
|
||||||
return get_json_result(code=settings.RetCode.EXCEPTION_ERROR, message="No chunk found, please upload file and parse it.")
|
return get_json_result(code=settings.RetCode.EXCEPTION_ERROR, message="No chunk found, please upload file and parse it.")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user