Skip to content

Commit

Permalink
feat: improve error logs
Browse files Browse the repository at this point in the history
  • Loading branch information
geekdada committed Jun 11, 2023
1 parent 9ea0769 commit a695a5e
Show file tree
Hide file tree
Showing 26 changed files with 311 additions and 135 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ module.exports = {
'@typescript-eslint/ban-ts-comment': 0,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
},
}
1 change: 1 addition & 0 deletions src/base-command.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'source-map-support/register'
import { Command, Flags, Interfaces, Config } from '@oclif/core'
import { transports } from '@surgio/logger'
import ora from 'ora'
Expand Down
74 changes: 56 additions & 18 deletions src/generator/artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Environment } from 'nunjucks'
import path from 'path'

import {
CustomProvider,
GetNodeListParams,
getProvider,
PossibleProviderType,
Expand All @@ -18,7 +19,7 @@ import {
PossibleNodeConfigType,
ProviderConfig,
RemoteSnippet,
ThenArg,
SupportProviderEnum,
} from '../types'
import {
getClashNodeNames,
Expand All @@ -39,7 +40,10 @@ import {
getSurgeWireguardNodes,
getUrl,
getV2rayNNodes,
isError,
isIp,
isSurgioError,
SurgioError,
toBase64,
toUrlSafeBase64,
} from '../utils'
Expand Down Expand Up @@ -84,8 +88,7 @@ export class Artifact extends EventEmitter {
public providerNameList: ReadonlyArray<string>
public nodeConfigListMap: Map<string, ReadonlyArray<PossibleNodeConfigType>> =
new Map()
public providerMap: Map<string, ThenArg<ReturnType<typeof getProvider>>> =
new Map()
public providerMap: Map<string, PossibleProviderType> = new Map()
public nodeList: PossibleNodeConfigType[] = []

private customFilters: NonNullable<ProviderConfig['customFilters']> = {}
Expand Down Expand Up @@ -297,25 +300,60 @@ export class Artifact extends EventEmitter {
provider = await getProvider(providerName, require(filePath))
this.providerMap.set(providerName, provider)
} catch (err) /* istanbul ignore next */ {
throw new Error(
`处理 Provider ${providerName} 时出现错误\n文件地址: ${filePath}`,
{
cause: err,
},
)
if (isSurgioError(err)) {
err.providerName = providerName
err.providerPath = filePath
throw err
} else {
throw new SurgioError(
isError(err) ? err.message : '处理 Provider 失败',
{
cause: err,
providerName,
providerPath: filePath,
},
)
}
}

try {
nodeConfigList = await provider.getNodeList(
this.getMergedCustomParams(getNodeListParams),
)
try {
nodeConfigList = await provider.getNodeList(
this.getMergedCustomParams(getNodeListParams),
)
} catch (err) {
if (provider.config.hooks?.onError) {
const result = await provider.config.hooks.onError(err)

if (Array.isArray(result)) {
const adHocProvider = new CustomProvider('ad-hoc', {
type: SupportProviderEnum.Custom,
nodeList: result,
})

nodeConfigList = await adHocProvider.getNodeList()
} else {
nodeConfigList = []
}
} else {
throw err
}
}
} catch (err) /* istanbul ignore next */ {
throw new Error(
`获取 Provider ${providerName} 节点时出现错误\n文件地址: ${filePath}`,
{
cause: err,
},
)
if (isSurgioError(err)) {
err.providerName = providerName
err.providerPath = filePath
throw err
} else {
throw new SurgioError(
isError(err) ? err.message : '处理 Provider 失败',
{
cause: err,
providerName,
providerPath: filePath,
},
)
}
}

// Filter 仅使用第一个 Provider 中的定义
Expand Down
6 changes: 2 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ export const utils = {
isAWS,
isFlyIO,
isAWSLambda,
}
} as const

export const categories = {
...CATEGORIES,
}
export const categories = CATEGORIES
1 change: 1 addition & 0 deletions src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PackageJson } from 'type-fest'

export { isZodError, isSurgioError, SurgioError } from './utils'
export * from './utils/cache'
export * from './types'

Expand Down
6 changes: 5 additions & 1 deletion src/provider/BlackSSLProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
NodeTypeEnum,
SubscriptionUserinfo,
} from '../types'
import { SurgioError } from '../utils'
import { ConfigCache } from '../utils/cache'
import httpClient from '../utils/http-client'
import Provider from './Provider'
Expand All @@ -29,7 +30,10 @@ export default class BlackSSLProvider extends Provider {

// istanbul ignore next
if (!result.success) {
throw result.error
throw new SurgioError('BlackSSLProvider 配置校验失败', {
cause: result.error,
providerName: name,
})
}

this.username = result.data.username
Expand Down
7 changes: 5 additions & 2 deletions src/provider/ClashProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
TuicNodeConfig,
VmessNodeConfig,
} from '../types'
import { lowercaseHeaderKeys } from '../utils'
import { lowercaseHeaderKeys, SurgioError } from '../utils'
import { getNetworkClashUA } from '../utils/env-flag'
import relayableUrl from '../utils/relayable-url'
import Provider from './Provider'
Expand Down Expand Up @@ -54,7 +54,10 @@ export default class ClashProvider extends Provider {

// istanbul ignore next
if (!result.success) {
throw result.error
throw new SurgioError('ClashProvider 配置校验失败', {
cause: result.error,
providerName: name,
})
}

this.#originalUrl = result.data.url
Expand Down
129 changes: 70 additions & 59 deletions src/provider/CustomProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
NodeTypeEnum,
PossibleNodeConfigType,
} from '../types'
import { SurgioError } from '../utils'
import Provider from './Provider'
import {
WireguardNodeConfigValidator,
Expand Down Expand Up @@ -40,7 +41,10 @@ export default class CustomProvider extends Provider {

// istanbul ignore next
if (!result.success) {
throw result.error
throw new SurgioError('CustomProvider 配置校验失败', {
cause: result.error,
providerName: name,
})
}

this.nodeList = result.data.nodeList
Expand All @@ -59,81 +63,88 @@ export default class CustomProvider extends Provider {
nodeList = this.nodeList
}

for (const node of nodeList) {
const type = node.type as NodeTypeEnum

// istanbul ignore next
if (node['udp-relay']) {
throw new Error('udp-relay is abandoned, please use udpRelay instead')
}

// istanbul ignore next
if (node['obfs-host']) {
throw new Error('obfs-host is abandoned, please use obfsHost instead')
}
nodeList.forEach((node, index) => {
try {
const type = node.type as NodeTypeEnum

// istanbul ignore next
if (node['obfs-uri']) {
throw new Error('obfs-uri is abandoned, please use obfsUri instead')
}
// istanbul ignore next
if (node['udp-relay']) {
throw new Error('udp-relay 已废弃, 请使用 udpRelay')
}

const parsedNode = (() => {
switch (type) {
case NodeTypeEnum.Shadowsocks:
return ShadowsocksNodeConfigValidator.parse(node)
// istanbul ignore next
if (node['obfs-host']) {
throw new Error('obfs-host 已废弃, 请使用 obfsHost')
}

case NodeTypeEnum.Shadowsocksr:
return ShadowsocksrNodeConfigValidator.parse(node)
// istanbul ignore next
if (node['obfs-uri']) {
throw new Error('obfs-uri 已废弃, 请使用 obfsUri')
}

case NodeTypeEnum.Vmess:
return VmessNodeConfigValidator.parse(node)
const parsedNode = (() => {
switch (type) {
case NodeTypeEnum.Shadowsocks:
return ShadowsocksNodeConfigValidator.parse(node)

case NodeTypeEnum.Trojan:
return TrojanNodeConfigValidator.parse(node)
case NodeTypeEnum.Shadowsocksr:
return ShadowsocksrNodeConfigValidator.parse(node)

case NodeTypeEnum.Socks5:
return Socks5NodeConfigValidator.parse(node)
case NodeTypeEnum.Vmess:
return VmessNodeConfigValidator.parse(node)

case NodeTypeEnum.HTTP:
return HttpNodeConfigValidator.parse(node)
case NodeTypeEnum.Trojan:
return TrojanNodeConfigValidator.parse(node)

case NodeTypeEnum.HTTPS:
return HttpsNodeConfigValidator.parse(node)
case NodeTypeEnum.Socks5:
return Socks5NodeConfigValidator.parse(node)

case NodeTypeEnum.Snell:
return SnellNodeConfigValidator.parse(node)
case NodeTypeEnum.HTTP:
return HttpNodeConfigValidator.parse(node)

case NodeTypeEnum.Tuic:
return TuicNodeConfigValidator.parse(node)
case NodeTypeEnum.HTTPS:
return HttpsNodeConfigValidator.parse(node)

case NodeTypeEnum.Wireguard:
return WireguardNodeConfigValidator.parse(node)
case NodeTypeEnum.Snell:
return SnellNodeConfigValidator.parse(node)

default:
throw new TypeError(`Unexpected object: ${type}`)
}
})()
case NodeTypeEnum.Tuic:
return TuicNodeConfigValidator.parse(node)

const propertyKeysMustBeLowercase = ['wsHeaders'] as const
case NodeTypeEnum.Wireguard:
return WireguardNodeConfigValidator.parse(node)

if (this.underlyingProxy && !parsedNode.underlyingProxy) {
parsedNode.underlyingProxy = this.underlyingProxy
}
default:
throw new TypeError(`无法识别的节点类型:${type}`)
}
})()
const propertyKeysMustBeLowercase = ['wsHeaders'] as const

propertyKeysMustBeLowercase.forEach((key) => {
if (key in parsedNode && parsedNode[key] !== undefined) {
parsedNode[key] = Object.keys(parsedNode[key] as any).reduce(
(acc: any, curr) => {
acc[curr.toLowerCase()] = (parsedNode[key] as any)[curr]
return acc
},
{},
)
if (this.underlyingProxy && !parsedNode.underlyingProxy) {
parsedNode.underlyingProxy = this.underlyingProxy
}
})

parsedNodeList.push(parsedNode)
}
propertyKeysMustBeLowercase.forEach((key) => {
if (key in parsedNode && parsedNode[key] !== undefined) {
parsedNode[key] = Object.keys(parsedNode[key] as any).reduce(
(acc: any, curr) => {
acc[curr.toLowerCase()] = (parsedNode[key] as any)[curr]
return acc
},
{},
)
}
})

parsedNodeList.push(parsedNode)
} catch (err) {
throw new SurgioError('节点配置校验失败', {
providerName: this.name,
nodeIndex: index,
cause: err,
})
}
})

if (this.config.hooks?.afterNodeListResponse) {
const newList = await this.config.hooks.afterNodeListResponse(
Expand Down
12 changes: 10 additions & 2 deletions src/provider/Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import {
import { getConfig } from '../config'
import { getProviderCacheMaxage } from '../utils/env-flag'
import httpClient, { getUserAgent } from '../utils/http-client'
import { msToSeconds, toMD5, parseSubscriptionUserInfo } from '../utils'
import {
msToSeconds,
toMD5,
parseSubscriptionUserInfo,
SurgioError,
} from '../utils'
import { ProviderValidator } from '../validators'
import { GetNodeListFunction, GetSubscriptionUserInfoFunction } from './types'

Expand All @@ -32,7 +37,10 @@ export default abstract class Provider {

// istanbul ignore next
if (!result.success) {
throw result.error
throw new SurgioError('Provider 配置校验失败', {
cause: result.error,
providerName: name,
})
}

this.supportGetSubscriptionUserInfo = false
Expand Down
Loading

0 comments on commit a695a5e

Please sign in to comment.