Fix remote control when Clash server is unavailable

This commit is contained in:
世界 2026-06-15 13:02:09 +08:00
parent b1ce685d1a
commit 7be0e1b62a
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 15 additions and 21 deletions

View file

@ -510,7 +510,7 @@ func (s *StartedService) GetClashModeStatus(ctx context.Context, empty *emptypb.
clashServer := s.instance.clashServer
s.serviceAccess.RUnlock()
if clashServer == nil {
return nil, status.Error(codes.Unimplemented, "clash mode not available")
return nil, status.Error(codes.NotFound, "clash mode not available")
}
return &ClashModeStatus{
ModeList: clashServer.ModeList(),
@ -537,7 +537,7 @@ func (s *StartedService) SubscribeClashMode(empty *emptypb.Empty, server grpc.Se
clashServer := s.instance.clashServer
if clashServer == nil {
s.serviceAccess.RUnlock()
return status.Error(codes.Unimplemented, "clash mode not available")
return status.Error(codes.NotFound, "clash mode not available")
}
message := &ClashMode{Mode: clashServer.Mode()}
s.serviceAccess.RUnlock()
@ -566,7 +566,7 @@ func (s *StartedService) SetClashMode(ctx context.Context, request *ClashMode) (
clashServer := s.instance.clashServer
s.serviceAccess.RUnlock()
if clashServer == nil {
return nil, status.Error(codes.Unimplemented, "clash mode not available")
return nil, status.Error(codes.NotFound, "clash mode not available")
}
clashServer.SetMode(request.Mode)
return &emptypb.Empty{}, nil

View file

@ -112,6 +112,3 @@ Update interval of the dashboard.
#### tls
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
Connection tracking and Clash mode methods require [Clash API](/configuration/experimental/clash-api/)
to be configured, otherwise they fail with `UNIMPLEMENTED`.

View file

@ -106,6 +106,3 @@ API 密钥。
#### tls
TLS 配置,参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
连接跟踪与 Clash 模式方法需要配置 [Clash API](/zh/configuration/experimental/clash-api/),
否则将以 `UNIMPLEMENTED` 失败。

View file

@ -456,23 +456,17 @@ func (c *CommandClient) handleClashModeStream() {
modeStatus, err := client.GetClashModeStatus(ctx, &emptypb.Empty{})
if err != nil {
c.handler.Disconnected(E.Cause(err, "get clash mode status").Error())
return
if status.Code(err) != codes.NotFound {
c.handler.Disconnected(E.Cause(err, "get clash mode status").Error())
return
}
modeStatus = &daemon.ClashModeStatus{}
}
if sFixAndroidStack {
go func() {
c.handler.InitializeClashMode(newIterator(modeStatus.ModeList), modeStatus.CurrentMode)
if len(modeStatus.ModeList) == 0 {
c.handler.Disconnected(E.Cause(os.ErrInvalid, "empty clash mode list").Error())
}
}()
go c.handler.InitializeClashMode(newIterator(modeStatus.ModeList), modeStatus.CurrentMode)
} else {
c.handler.InitializeClashMode(newIterator(modeStatus.ModeList), modeStatus.CurrentMode)
if len(modeStatus.ModeList) == 0 {
c.handler.Disconnected(E.Cause(os.ErrInvalid, "empty clash mode list").Error())
return
}
}
if len(modeStatus.ModeList) == 0 {
@ -481,6 +475,9 @@ func (c *CommandClient) handleClashModeStream() {
stream, err := client.SubscribeClashMode(ctx, &emptypb.Empty{})
if err != nil {
if status.Code(err) == codes.NotFound {
return
}
c.handler.Disconnected(E.Cause(err, "subscribe clash mode").Error())
return
}
@ -488,6 +485,9 @@ func (c *CommandClient) handleClashModeStream() {
for {
mode, err := stream.Recv()
if err != nil {
if status.Code(err) == codes.NotFound {
return
}
c.handler.Disconnected(E.Cause(err, "clash mode stream recv").Error())
return
}