fix: use common.Marshal/Unmarshal per Rule 1 + telegram null safety
- model/user.go: replace json.Unmarshal/Marshal with common.* wrapper functions as required by project Rule 1 (3 occurrences) - relay/channel/claude/relay-claude.go: replace 3 json.* calls with common.* (tool call args unmarshal, response marshal) - relay/channel/gemini/relay-gemini.go: replace 5 json.* calls with common.* (content parsing, function args, response marshal) - adapters/telegram/index.ts: add optional chaining on callback query message.chat.id and null coalescing on message.text to prevent crash when callback message is undefined Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -718,7 +718,7 @@ bot.on('callback_query:data', async (ctx) => {
|
||||
|
||||
const requestId = parts[1]!
|
||||
const allowed = parts[2] === 'yes'
|
||||
const chatId = String(ctx.callbackQuery.message?.chat.id)
|
||||
const chatId = String(ctx.callbackQuery.message?.chat?.id)
|
||||
|
||||
bridge.sendPermissionResponse(chatId, requestId, allowed)
|
||||
const runtime = getRuntimeState(chatId)
|
||||
@@ -727,7 +727,7 @@ bot.on('callback_query:data', async (ctx) => {
|
||||
const statusText = allowed ? '✅ 已允许' : '❌ 已拒绝'
|
||||
try {
|
||||
await ctx.editMessageText(
|
||||
ctx.callbackQuery.message?.text + `\n\n${statusText}`,
|
||||
(ctx.callbackQuery.message?.text ?? '') + `\n\n${statusText}`,
|
||||
)
|
||||
} catch { /* ignore */ }
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package model
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -81,7 +80,7 @@ func (user *User) SetAccessToken(token string) {
|
||||
func (user *User) GetSetting() dto.UserSetting {
|
||||
setting := dto.UserSetting{}
|
||||
if user.Setting != "" {
|
||||
err := json.Unmarshal([]byte(user.Setting), &setting)
|
||||
err := common.Unmarshal([]byte(user.Setting), &setting)
|
||||
if err != nil {
|
||||
common.SysLog("failed to unmarshal setting: " + err.Error())
|
||||
}
|
||||
@@ -90,7 +89,7 @@ func (user *User) GetSetting() dto.UserSetting {
|
||||
}
|
||||
|
||||
func (user *User) SetSetting(setting dto.UserSetting) {
|
||||
settingBytes, err := json.Marshal(setting)
|
||||
settingBytes, err := common.Marshal(setting)
|
||||
if err != nil {
|
||||
common.SysLog("failed to marshal setting: " + err.Error())
|
||||
return
|
||||
@@ -151,7 +150,7 @@ func generateDefaultSidebarConfigForRole(userRole int) string {
|
||||
// 普通用户不包含admin区域
|
||||
|
||||
// 转换为JSON字符串
|
||||
configBytes, err := json.Marshal(defaultConfig)
|
||||
configBytes, err := common.Marshal(defaultConfig)
|
||||
if err != nil {
|
||||
common.SysLog("生成默认边栏配置失败: " + err.Error())
|
||||
return ""
|
||||
|
||||
@@ -406,7 +406,7 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
|
||||
if message.ToolCalls != nil {
|
||||
for _, toolCall := range message.ParseToolCalls() {
|
||||
inputObj := make(map[string]any)
|
||||
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &inputObj); err != nil {
|
||||
if err := common.Unmarshal([]byte(toolCall.Function.Arguments), &inputObj); err != nil {
|
||||
common.SysLog("tool call function arguments is not a map[string]any: " + fmt.Sprintf("%v", toolCall.Function.Arguments))
|
||||
continue
|
||||
}
|
||||
@@ -540,7 +540,7 @@ func ResponseClaude2OpenAI(claudeResponse *dto.ClaudeResponse) *dto.OpenAITextRe
|
||||
for _, message := range claudeResponse.Content {
|
||||
switch message.Type {
|
||||
case "tool_use":
|
||||
args, _ := json.Marshal(message.Input)
|
||||
args, _ := common.Marshal(message.Input)
|
||||
tools = append(tools, dto.ToolCallResponse{
|
||||
ID: message.Id,
|
||||
Type: "function", // compatible with other OpenAI derivative applications
|
||||
@@ -919,7 +919,7 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
|
||||
case types.RelayFormatOpenAI:
|
||||
openaiResponse := ResponseClaude2OpenAI(&claudeResponse)
|
||||
openaiResponse.Usage = buildOpenAIStyleUsageFromClaudeUsage(claudeInfo.Usage)
|
||||
responseData, err = json.Marshal(openaiResponse)
|
||||
responseData, err = common.Marshal(openaiResponse)
|
||||
if err != nil {
|
||||
return types.NewError(err, types.ErrorCodeBadResponseBody)
|
||||
}
|
||||
|
||||
@@ -467,10 +467,10 @@ func CovertOpenAI2Gemini(c *gin.Context, textRequest dto.GeneralOpenAIRequest, i
|
||||
contentStr := message.StringContent()
|
||||
|
||||
// 1. 尝试解析为 JSON 对象
|
||||
if err := json.Unmarshal([]byte(contentStr), &contentMap); err != nil {
|
||||
if err := common.Unmarshal([]byte(contentStr), &contentMap); err != nil {
|
||||
// 2. 如果失败,尝试解析为 JSON 数组
|
||||
var contentSlice []interface{}
|
||||
if err := json.Unmarshal([]byte(contentStr), &contentSlice); err == nil {
|
||||
if err := common.Unmarshal([]byte(contentStr), &contentSlice); err == nil {
|
||||
// 如果是数组,包装成对象
|
||||
contentMap = map[string]interface{}{"result": contentSlice}
|
||||
} else {
|
||||
@@ -502,7 +502,7 @@ func CovertOpenAI2Gemini(c *gin.Context, textRequest dto.GeneralOpenAIRequest, i
|
||||
for _, call := range message.ParseToolCalls() {
|
||||
args := map[string]interface{}{}
|
||||
if call.Function.Arguments != "" {
|
||||
if json.Unmarshal([]byte(call.Function.Arguments), &args) != nil {
|
||||
if common.Unmarshal([]byte(call.Function.Arguments), &args) != nil {
|
||||
return nil, fmt.Errorf("invalid arguments for function %s, args: %s", call.Function.Name, call.Function.Arguments)
|
||||
}
|
||||
}
|
||||
@@ -994,9 +994,7 @@ func unescapeMapOrSlice(data interface{}) interface{} {
|
||||
func getResponseToolCall(item *dto.GeminiPart) *dto.ToolCallResponse {
|
||||
var argsBytes []byte
|
||||
var err error
|
||||
// 移除 unescapeMapOrSlice 调用,直接使用 json.Marshal
|
||||
// JSON 序列化/反序列化已经正确处理了转义字符
|
||||
argsBytes, err = json.Marshal(item.FunctionCall.Arguments)
|
||||
argsBytes, err = common.Marshal(item.FunctionCall.Arguments)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
@@ -1569,7 +1567,7 @@ func GeminiImageHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.
|
||||
})
|
||||
}
|
||||
|
||||
jsonResponse, jsonErr := json.Marshal(openAIResponse)
|
||||
jsonResponse, jsonErr := common.Marshal(openAIResponse)
|
||||
if jsonErr != nil {
|
||||
return nil, types.NewError(jsonErr, types.ErrorCodeBadResponseBody)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user