Private
Public Access
1
0
Files
u-desk/internal/sftp/errors.go
绝尘 6bee55b96f 新增:SFTP直连+连接池+autoConnect+文件服务器端口自动回退
- SFTP模块:连接/断开/文件CRUD/系统信息采集/base64二进制写入
- 连接池:多服务器同时在线,瞬间切换profile
- autoConnect:启动时自动连接所有非本地服务器
- 端口自动回退:listenWithFallback消除TOCTOU,解决端口冲突崩溃
- 文件服务器URL集中管理:file-server.ts消除8+处硬编码端口
- Sidebar设置面板:添加服务器/自动连接/自动刷新开关
- 修复:validateFilePath越界panic、正则预编译
- 修复:注释准确性(RemoveAll/端口8073/动态端口文档)
2026-05-04 15:33:19 +08:00

70 lines
2.2 KiB
Go

package sftp
import (
"errors"
"fmt"
"strings"
)
// ConnectionError SFTP 连接错误(区分阶段)
type ConnectionError struct {
Op string // dial / handshake / auth / sftp_init
Err error
}
func (e *ConnectionError) Error() string {
return fmt.Sprintf("SFTP 连接失败 [%s]: %v", e.Op, e.Err)
}
func (e *ConnectionError) Unwrap() error { return e.Err }
// ToUserMessage 将底层错误转换为用户友好的中文错误(返回 error 类型)
func ToUserMessage(err error) error {
if err == nil {
return nil
}
var connErr *ConnectionError
if errors.As(err, &connErr) {
switch connErr.Op {
case "dial":
return fmt.Errorf("无法连接到服务器 (%v)。请检查地址和端口是否正确", connErr.Err)
case "handshake":
return fmt.Errorf("SSH 握手失败,请检查服务是否正常运行")
case "auth":
return fmt.Errorf("认证失败,请检查用户名和密码/密钥是否正确")
case "sftp_init":
return fmt.Errorf("SFTP 子系统初始化失败,请确认远程服务器支持 SFTP")
}
}
msg := err.Error()
switch {
case strings.Contains(msg, "unable authenticate"), strings.Contains(msg, "no auth method"):
return fmt.Errorf("认证失败:用户名或密码/密钥不正确")
case strings.Contains(msg, "connection refused"):
return fmt.Errorf("连接被拒绝:目标机器可能未开启 SSH 服务")
case strings.Contains(msg, "timeout"), strings.Contains(msg, "i/o timeout"):
return fmt.Errorf("连接超时:请检查网络连通性或防火墙设置")
case strings.Contains(msg, "host key mismatch"):
return fmt.Errorf("主机密钥不匹配:可能存在中间人攻击风险")
case strings.Contains(msg, "permission denied"):
return fmt.Errorf("权限不足:当前用户无权访问该资源")
case strings.Contains(msg, "no such file"), strings.Contains(msg, "not found"):
return fmt.Errorf("文件或目录不存在")
default:
return err
}
}
// isNetworkError 判断是否为网络层错误(需要重连)
func isNetworkError(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "broken pipe") ||
strings.Contains(msg, "connection reset") ||
strings.Contains(msg, "timeout")
}