@sovovs/bycli 2.1.26 → 2.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AuthRequiredError, CommandExecutionError, EmptyResultError,
|
|
2
|
+
AuthRequiredError, CliError, CommandExecutionError, EmptyResultError, RateLimitedError,
|
|
3
3
|
} from '@sovovs/bycli/errors';
|
|
4
4
|
import { buildSecretSet, redactText } from './redact.js';
|
|
5
5
|
|
|
@@ -16,12 +16,17 @@ function safePhase(error, secrets) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export function isEligibleArticleFallbackError(error) {
|
|
19
|
-
return error instanceof CommandExecutionError
|
|
19
|
+
return error instanceof CommandExecutionError
|
|
20
|
+
|| error instanceof EmptyResultError
|
|
21
|
+
|| (error instanceof CliError && error.code === 'RATE_LIMITED');
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export function withMissingFallbackName(operation, error) {
|
|
23
25
|
const hint = `${error.hint ? `${error.hint} ` : ''}Sogou fallback requires the exact official-account name in --name.`;
|
|
24
26
|
if (error instanceof EmptyResultError) return new EmptyResultError(operation, hint);
|
|
27
|
+
if (error instanceof CliError && error.code === 'RATE_LIMITED') {
|
|
28
|
+
return new RateLimitedError(error.message, hint);
|
|
29
|
+
}
|
|
25
30
|
return new CommandExecutionError(error.message, hint);
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -31,11 +36,17 @@ export function combineArticleFallbackErrors({
|
|
|
31
36
|
fallbackError,
|
|
32
37
|
credentials,
|
|
33
38
|
}) {
|
|
34
|
-
if (fallbackError instanceof AuthRequiredError) return fallbackError;
|
|
35
39
|
const secrets = buildSecretSet(credentials);
|
|
36
40
|
const primary = safePhase(primaryError, secrets);
|
|
37
41
|
const fallback = safePhase(fallbackError, secrets);
|
|
38
42
|
const hint = `Primary (${primary.code}): ${primary.summary}; fallback (${fallback.code}): ${fallback.summary}`;
|
|
43
|
+
if (primaryError instanceof CliError && primaryError.code === 'RATE_LIMITED') {
|
|
44
|
+
return new RateLimitedError(
|
|
45
|
+
'Weixin article index was rate limited and Sogou fallback failed',
|
|
46
|
+
hint,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (fallbackError instanceof AuthRequiredError) return fallbackError;
|
|
39
50
|
if (primaryError instanceof EmptyResultError && fallbackError instanceof EmptyResultError) {
|
|
40
51
|
return new EmptyResultError(operation, hint);
|
|
41
52
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthRequiredError, CommandExecutionError } from '@sovovs/bycli/errors';
|
|
1
|
+
import { AuthRequiredError, CommandExecutionError, RateLimitedError } from '@sovovs/bycli/errors';
|
|
2
2
|
import { buildSecretSet, redactText } from './redact.js';
|
|
3
3
|
|
|
4
4
|
const DOMAIN = 'mp.weixin.qq.com';
|
|
@@ -34,8 +34,8 @@ export function mapArticleIndexPayload(payload) {
|
|
|
34
34
|
throw new AuthRequiredError(DOMAIN, 'WeChat article-index credentials have expired');
|
|
35
35
|
}
|
|
36
36
|
if (ret === 200013 && normalizedMessage === 'freq control') {
|
|
37
|
-
throw
|
|
38
|
-
'was rate limited (ret=200013)',
|
|
37
|
+
throw new RateLimitedError(
|
|
38
|
+
'WeChat appmsgpublish was rate limited (ret=200013)',
|
|
39
39
|
'Wait before retrying the WeChat article-index request; repeated retries may extend frequency control.',
|
|
40
40
|
);
|
|
41
41
|
}
|
|
@@ -122,6 +122,10 @@ function transportError(error, credentials) {
|
|
|
122
122
|
const redactedHint = hint ? redactText(hint, secrets) : undefined;
|
|
123
123
|
if (error instanceof AuthRequiredError && error.domain === DOMAIN
|
|
124
124
|
&& redactedMessage === message && redactedHint === hint) return error;
|
|
125
|
+
if (error instanceof RateLimitedError) {
|
|
126
|
+
if (redactedMessage === message && redactedHint === hint) return error;
|
|
127
|
+
return new RateLimitedError(redactedMessage, redactedHint);
|
|
128
|
+
}
|
|
125
129
|
if (isWechatVerificationResponse(redactedMessage, redactedHint)) {
|
|
126
130
|
return new AuthRequiredError(
|
|
127
131
|
DOMAIN,
|
package/dist/src/errors.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* 2 Argument / usage error (ArgumentError)
|
|
15
15
|
* 66 No input / empty result (EmptyResultError)
|
|
16
16
|
* 69 Service unavailable (BrowserConnectError, adapter load failures)
|
|
17
|
-
* 75 Temporary failure, retry later (TimeoutError) EX_TEMPFAIL
|
|
17
|
+
* 75 Temporary failure, retry later (TimeoutError, RateLimitedError) EX_TEMPFAIL
|
|
18
18
|
* 77 Permission denied / auth needed (AuthRequiredError)
|
|
19
19
|
* 78 Configuration error (ConfigError)
|
|
20
20
|
* 130 Interrupted by Ctrl-C (set by tui.ts SIGINT handler)
|
|
@@ -51,6 +51,9 @@ export declare class BrowserConnectError extends CliError {
|
|
|
51
51
|
export declare class CommandExecutionError extends CliError {
|
|
52
52
|
constructor(message: string, hint?: string);
|
|
53
53
|
}
|
|
54
|
+
export declare class RateLimitedError extends CliError {
|
|
55
|
+
constructor(message: string, hint?: string);
|
|
56
|
+
}
|
|
54
57
|
export declare class ConfigError extends CliError {
|
|
55
58
|
constructor(message: string, hint?: string);
|
|
56
59
|
}
|
package/dist/src/errors.js
CHANGED
|
@@ -59,6 +59,11 @@ export class CommandExecutionError extends CliError {
|
|
|
59
59
|
super('COMMAND_EXEC', message, hint, EXIT_CODES.GENERIC_ERROR);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
export class RateLimitedError extends CliError {
|
|
63
|
+
constructor(message, hint) {
|
|
64
|
+
super('RATE_LIMITED', message, hint, EXIT_CODES.TEMPFAIL);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
62
67
|
export class ConfigError extends CliError {
|
|
63
68
|
constructor(message, hint) {
|
|
64
69
|
super('CONFIG', message, hint, EXIT_CODES.CONFIG_ERROR);
|