provider: Fix startup failure when restoring an empty subscription cache

Decode cached subscription data as serialized options, allowing an empty
outbound list produced by include/exclude filters. Empty providers now
use the existing Compatible group fallback instead of failing startup.

Share outbound filtering and application between cache restoration and
subscription updates.
This commit is contained in:
Mikhail Zhdanov
2026-09-30 19:56:01 +07:00
parent 55faa763f9
commit d75ac4ea21
+8 -2
View File
@@ -115,9 +115,11 @@ func (s *ProviderRemote) Start() error {
s.subscriptionInfo = info
content, _ = boxCommon.DecodeBase64URLSafe(others)
}
if err := s.updateProviderFromContent(content); err != nil {
cachedOptions, err := json.UnmarshalExtendedContext[option.Options](s.ctx, []byte(content))
if err != nil {
return E.Cause(err, "restore cached outbound provider")
}
s.updateProviderFromOptions(cachedOptions.Outbounds)
s.UpdateGroups()
s.lastUpdated, s.lastEtag = saveSub.LastUpdated, saveSub.LastEtag
}
@@ -300,12 +302,16 @@ func (s *ProviderRemote) updateProviderFromContent(content string) error {
if err != nil {
return err
}
s.updateProviderFromOptions(outboundOpts)
return nil
}
func (s *ProviderRemote) updateProviderFromOptions(outboundOpts []option.Outbound) {
outboundOpts = common.Filter(outboundOpts, func(it option.Outbound) bool {
return (s.exclude == nil || !s.exclude.MatchString(it.Tag)) && (s.include == nil || s.include.MatchString(it.Tag))
})
s.UpdateOutbounds(s.lastOutOpts, outboundOpts)
s.lastOutOpts = outboundOpts
return nil
}
func getFirstLine(content string) (string, string) {