@debugbundle/cli 0.1.4 → 0.1.6
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.
- package/README.md +1 -0
- package/dist/main.cjs +211 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ debugbundle setup --non-interactive
|
|
|
21
21
|
debugbundle doctor --privacy
|
|
22
22
|
debugbundle verify local
|
|
23
23
|
debugbundle verify cloud --project-id <id> --trigger-5xx
|
|
24
|
+
debugbundle verify cloud --project-id <id> --trigger-4xx 403
|
|
24
25
|
debugbundle process
|
|
25
26
|
debugbundle incidents
|
|
26
27
|
debugbundle explain <incident-id> --source cloud
|
package/dist/main.cjs
CHANGED
|
@@ -14485,6 +14485,31 @@ var CaptureProbeEventsValues = ["buffer_only", "standalone_when_activated"];
|
|
|
14485
14485
|
var CaptureProbeEventsSchema = external_exports.enum(CaptureProbeEventsValues);
|
|
14486
14486
|
var RequestSignalClassificationValues = ["incident_signal", "context_signal"];
|
|
14487
14487
|
var RequestSignalClassificationSchema = external_exports.enum(RequestSignalClassificationValues);
|
|
14488
|
+
var RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES = [401, 403, 409, 422];
|
|
14489
|
+
var ImmediateClientErrorStatusSchema = external_exports.number().int().min(400).max(499);
|
|
14490
|
+
function normalizeImmediateClientErrorStatuses(statuses) {
|
|
14491
|
+
return Array.from(new Set(statuses)).sort((left, right) => left - right);
|
|
14492
|
+
}
|
|
14493
|
+
var ImmediateClientErrorStatusesSchema = external_exports.array(ImmediateClientErrorStatusSchema).max(12).transform((statuses) => normalizeImmediateClientErrorStatuses(statuses));
|
|
14494
|
+
var ResolvedCapturePolicySchema = external_exports.object({
|
|
14495
|
+
preset: CapturePresetSchema,
|
|
14496
|
+
capture_logs: CaptureLogsSchema,
|
|
14497
|
+
capture_request_events: CaptureRequestEventsSchema,
|
|
14498
|
+
capture_breadcrumbs: CaptureBreadcrumbsSchema,
|
|
14499
|
+
capture_probe_events: CaptureProbeEventsSchema,
|
|
14500
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema
|
|
14501
|
+
});
|
|
14502
|
+
var CapturePolicyOverridesSchema = external_exports.object({
|
|
14503
|
+
capture_logs: CaptureLogsSchema.nullable(),
|
|
14504
|
+
capture_request_events: CaptureRequestEventsSchema.nullable(),
|
|
14505
|
+
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable(),
|
|
14506
|
+
capture_probe_events: CaptureProbeEventsSchema.nullable(),
|
|
14507
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable()
|
|
14508
|
+
});
|
|
14509
|
+
var CapturePolicyResponseSchema = external_exports.object({
|
|
14510
|
+
policy: ResolvedCapturePolicySchema,
|
|
14511
|
+
overrides: CapturePolicyOverridesSchema
|
|
14512
|
+
});
|
|
14488
14513
|
var CapturePolicySchema = external_exports.object({
|
|
14489
14514
|
project_id: external_exports.string().uuid(),
|
|
14490
14515
|
preset: CapturePresetSchema,
|
|
@@ -14492,6 +14517,7 @@ var CapturePolicySchema = external_exports.object({
|
|
|
14492
14517
|
capture_request_events: CaptureRequestEventsSchema.nullable(),
|
|
14493
14518
|
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable(),
|
|
14494
14519
|
capture_probe_events: CaptureProbeEventsSchema.nullable(),
|
|
14520
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable(),
|
|
14495
14521
|
updated_at: external_exports.string().datetime()
|
|
14496
14522
|
});
|
|
14497
14523
|
var CapturePolicyUpdateSchema = external_exports.object({
|
|
@@ -14499,21 +14525,48 @@ var CapturePolicyUpdateSchema = external_exports.object({
|
|
|
14499
14525
|
capture_logs: CaptureLogsSchema.nullable().optional(),
|
|
14500
14526
|
capture_request_events: CaptureRequestEventsSchema.nullable().optional(),
|
|
14501
14527
|
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable().optional(),
|
|
14502
|
-
capture_probe_events: CaptureProbeEventsSchema.nullable().optional()
|
|
14528
|
+
capture_probe_events: CaptureProbeEventsSchema.nullable().optional(),
|
|
14529
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable().optional()
|
|
14503
14530
|
});
|
|
14531
|
+
var PRESET_DEFAULTS = {
|
|
14532
|
+
minimal: {
|
|
14533
|
+
capture_logs: "error",
|
|
14534
|
+
capture_request_events: "failures_only",
|
|
14535
|
+
capture_breadcrumbs: "local_only",
|
|
14536
|
+
capture_probe_events: "buffer_only",
|
|
14537
|
+
immediate_client_error_statuses: []
|
|
14538
|
+
},
|
|
14539
|
+
balanced: {
|
|
14540
|
+
capture_logs: "warning",
|
|
14541
|
+
capture_request_events: "failures_only",
|
|
14542
|
+
capture_breadcrumbs: "exception_only",
|
|
14543
|
+
capture_probe_events: "buffer_only",
|
|
14544
|
+
immediate_client_error_statuses: []
|
|
14545
|
+
},
|
|
14546
|
+
investigative: {
|
|
14547
|
+
capture_logs: "info",
|
|
14548
|
+
capture_request_events: "all",
|
|
14549
|
+
capture_breadcrumbs: "standalone",
|
|
14550
|
+
capture_probe_events: "standalone_when_activated",
|
|
14551
|
+
immediate_client_error_statuses: [...RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES]
|
|
14552
|
+
}
|
|
14553
|
+
};
|
|
14504
14554
|
var BALANCED_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([408, 423, 424, 425, 429]);
|
|
14505
14555
|
var INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([...BALANCED_IMMEDIATE_REQUEST_STATUSES, 409]);
|
|
14506
14556
|
var BALANCED_STANDARD_ANOMALY_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 409, 422]);
|
|
14507
14557
|
var BALANCED_HIGH_VOLUME_ANOMALY_STATUSES = /* @__PURE__ */ new Set([400, 410]);
|
|
14508
14558
|
var INVESTIGATIVE_ANOMALY_STATUSES = /* @__PURE__ */ new Set([...BALANCED_STANDARD_ANOMALY_STATUSES, ...BALANCED_HIGH_VOLUME_ANOMALY_STATUSES]);
|
|
14509
14559
|
function classifyRequestStatus(input) {
|
|
14510
|
-
const { responseStatus, capturePreset } = input;
|
|
14560
|
+
const { responseStatus, capturePreset, immediateClientErrorStatuses = [] } = input;
|
|
14511
14561
|
if (responseStatus === null || !Number.isFinite(responseStatus)) {
|
|
14512
14562
|
return "context_signal";
|
|
14513
14563
|
}
|
|
14514
14564
|
if (responseStatus >= 500) {
|
|
14515
14565
|
return "incident_signal";
|
|
14516
14566
|
}
|
|
14567
|
+
if (immediateClientErrorStatuses.includes(responseStatus)) {
|
|
14568
|
+
return "incident_signal";
|
|
14569
|
+
}
|
|
14517
14570
|
if (capturePreset === "investigative") {
|
|
14518
14571
|
return INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES.has(responseStatus) ? "incident_signal" : "context_signal";
|
|
14519
14572
|
}
|
|
@@ -16565,7 +16618,7 @@ function getRequestResponseStatus(payload) {
|
|
|
16565
16618
|
const status = payload?.["response_status"];
|
|
16566
16619
|
return typeof status === "number" && Number.isFinite(status) ? status : null;
|
|
16567
16620
|
}
|
|
16568
|
-
function classifyEvent(eventType, logLevel, probeActivationId, payload, capturePreset = "minimal") {
|
|
16621
|
+
function classifyEvent(eventType, logLevel, probeActivationId, payload, capturePreset = "minimal", immediateClientErrorStatuses = []) {
|
|
16569
16622
|
switch (eventType) {
|
|
16570
16623
|
case "backend_exception":
|
|
16571
16624
|
case "frontend_exception":
|
|
@@ -16577,7 +16630,7 @@ function classifyEvent(eventType, logLevel, probeActivationId, payload, captureP
|
|
|
16577
16630
|
return "context_signal";
|
|
16578
16631
|
case "request_event": {
|
|
16579
16632
|
const responseStatus = getRequestResponseStatus(payload);
|
|
16580
|
-
return classifyRequestStatus({ responseStatus, capturePreset });
|
|
16633
|
+
return classifyRequestStatus({ responseStatus, capturePreset, immediateClientErrorStatuses });
|
|
16581
16634
|
}
|
|
16582
16635
|
case "frontend_breadcrumb":
|
|
16583
16636
|
case "deploy_metadata":
|
|
@@ -16680,6 +16733,13 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
16680
16733
|
ON slack_destinations (organization_id, is_active, created_at)
|
|
16681
16734
|
`
|
|
16682
16735
|
]
|
|
16736
|
+
}),
|
|
16737
|
+
defineStorageSchemaMigration({
|
|
16738
|
+
id: "202605140001_add_capture_policy_immediate_client_error_statuses",
|
|
16739
|
+
description: "Add nullable immediate client error status overrides to capture policies.",
|
|
16740
|
+
statements: [
|
|
16741
|
+
"ALTER TABLE capture_policies ADD COLUMN IF NOT EXISTS immediate_client_error_statuses jsonb"
|
|
16742
|
+
]
|
|
16683
16743
|
})
|
|
16684
16744
|
];
|
|
16685
16745
|
|
|
@@ -24530,7 +24590,7 @@ function formatResult(input, exitCode, checks, errors, incidentId) {
|
|
|
24530
24590
|
};
|
|
24531
24591
|
}
|
|
24532
24592
|
function buildCloudSuggestedActions(status, incidentId, mode = "passive_recent_incident") {
|
|
24533
|
-
if (status === "healthy" && incidentId !== void 0 && mode === "active_5xx") {
|
|
24593
|
+
if (status === "healthy" && incidentId !== void 0 && (mode === "active_5xx" || mode === "active_4xx")) {
|
|
24534
24594
|
return [
|
|
24535
24595
|
`Run debugbundle inspect ${incidentId} --source cloud to inspect why the incident fired.`,
|
|
24536
24596
|
`Run debugbundle bundle ${incidentId} --source cloud to fetch the generated debug bundle.`
|
|
@@ -24600,11 +24660,11 @@ function localFailureStepName(checks) {
|
|
|
24600
24660
|
function cloudVerificationRunId(now) {
|
|
24601
24661
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
24602
24662
|
}
|
|
24603
|
-
function requestFailureReason() {
|
|
24663
|
+
function requestFailureReason(responseStatus) {
|
|
24604
24664
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
24605
24665
|
event_type: "request_event",
|
|
24606
24666
|
event_class: "incident_signal",
|
|
24607
|
-
response_status:
|
|
24667
|
+
response_status: responseStatus
|
|
24608
24668
|
});
|
|
24609
24669
|
if (incidentReason === null) {
|
|
24610
24670
|
throw new Error("request_failure_reason_unavailable");
|
|
@@ -24613,6 +24673,9 @@ function requestFailureReason() {
|
|
|
24613
24673
|
}
|
|
24614
24674
|
function buildCloudVerificationEvent(input) {
|
|
24615
24675
|
const runId = cloudVerificationRunId(input.now);
|
|
24676
|
+
const is5xxVerification = input.responseStatus >= 500;
|
|
24677
|
+
const routeTemplate = is5xxVerification ? "/debugbundle/verify/cloud" : `/debugbundle/verify/cloud/client-error/${input.responseStatus}`;
|
|
24678
|
+
const verificationLabel = is5xxVerification ? "true" : `client-error-${input.responseStatus}`;
|
|
24616
24679
|
return createEventEnvelope({
|
|
24617
24680
|
event_type: "request_event",
|
|
24618
24681
|
sdk_name: "debugbundle-cli",
|
|
@@ -24626,28 +24689,39 @@ function buildCloudVerificationEvent(input) {
|
|
|
24626
24689
|
occurred_at: input.now.toISOString(),
|
|
24627
24690
|
payload: {
|
|
24628
24691
|
method: "GET",
|
|
24629
|
-
path:
|
|
24630
|
-
route_template:
|
|
24692
|
+
path: routeTemplate,
|
|
24693
|
+
route_template: routeTemplate,
|
|
24631
24694
|
query: {
|
|
24632
24695
|
debugbundle_verification: true,
|
|
24633
|
-
run_id: runId
|
|
24696
|
+
run_id: runId,
|
|
24697
|
+
synthetic_status: input.responseStatus
|
|
24634
24698
|
},
|
|
24635
24699
|
headers: {
|
|
24636
|
-
"x-debugbundle-verification":
|
|
24700
|
+
"x-debugbundle-verification": verificationLabel
|
|
24637
24701
|
},
|
|
24638
|
-
response_status:
|
|
24702
|
+
response_status: input.responseStatus,
|
|
24639
24703
|
duration_ms: 37,
|
|
24640
24704
|
response_headers: {
|
|
24641
|
-
"x-debugbundle-verification":
|
|
24705
|
+
"x-debugbundle-verification": verificationLabel
|
|
24642
24706
|
},
|
|
24643
24707
|
response_body: {
|
|
24644
|
-
error: "debugbundle_cloud_verification",
|
|
24708
|
+
error: is5xxVerification ? "debugbundle_cloud_verification" : "debugbundle_cloud_client_error_verification",
|
|
24645
24709
|
synthetic: true,
|
|
24646
|
-
run_id: runId
|
|
24710
|
+
run_id: runId,
|
|
24711
|
+
response_status: input.responseStatus
|
|
24647
24712
|
}
|
|
24648
24713
|
}
|
|
24649
24714
|
});
|
|
24650
24715
|
}
|
|
24716
|
+
function validateActiveCloudVerificationInput(input) {
|
|
24717
|
+
if (input.trigger5xx === true && input.trigger4xxStatus !== void 0) {
|
|
24718
|
+
return "Choose either --trigger-5xx or --trigger-4xx, not both.";
|
|
24719
|
+
}
|
|
24720
|
+
if (input.trigger4xxStatus !== void 0 && (input.trigger4xxStatus < 400 || input.trigger4xxStatus > 499)) {
|
|
24721
|
+
return "--trigger-4xx must be an integer status between 400 and 499.";
|
|
24722
|
+
}
|
|
24723
|
+
return null;
|
|
24724
|
+
}
|
|
24651
24725
|
async function sendEventsToApi2(input, dependencies = {}) {
|
|
24652
24726
|
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
24653
24727
|
const baseUrl = input.baseUrl.endsWith("/") ? input.baseUrl.slice(0, -1) : input.baseUrl;
|
|
@@ -24839,6 +24913,15 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24839
24913
|
const checks = [];
|
|
24840
24914
|
const environment = input.environment ?? "production";
|
|
24841
24915
|
const maxAgeMinutes = input.maxAgeMinutes ?? 15;
|
|
24916
|
+
const activeInputError = validateActiveCloudVerificationInput(input);
|
|
24917
|
+
if (activeInputError !== null) {
|
|
24918
|
+
checks.push({
|
|
24919
|
+
name: "trigger-input",
|
|
24920
|
+
status: "error",
|
|
24921
|
+
message: activeInputError
|
|
24922
|
+
});
|
|
24923
|
+
return formatCloudResult(input, 4, checks, [activeInputError]);
|
|
24924
|
+
}
|
|
24842
24925
|
const readAuthState = dependencies.readAuthState ?? readCliAuthState;
|
|
24843
24926
|
let authState;
|
|
24844
24927
|
try {
|
|
@@ -24871,7 +24954,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24871
24954
|
requestInput,
|
|
24872
24955
|
dependencies.fetchImpl === void 0 ? {} : { fetchImpl: dependencies.fetchImpl }
|
|
24873
24956
|
));
|
|
24874
|
-
if (input.trigger5xx === true) {
|
|
24957
|
+
if (input.trigger5xx === true || input.trigger4xxStatus !== void 0) {
|
|
24875
24958
|
const verificationStartedAt = now();
|
|
24876
24959
|
const runId = cloudVerificationRunId(verificationStartedAt);
|
|
24877
24960
|
const serviceName = input.service ?? `debugbundle-verify-cloud-${runId}`;
|
|
@@ -24879,16 +24962,20 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24879
24962
|
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
24880
24963
|
const pollIntervalMs = dependencies.pollIntervalMs ?? 2e3;
|
|
24881
24964
|
const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
24965
|
+
const responseStatus = input.trigger4xxStatus ?? 503;
|
|
24966
|
+
const activeMode = input.trigger4xxStatus !== void 0 ? "active_4xx" : "active_5xx";
|
|
24967
|
+
const activeCheckName = input.trigger4xxStatus !== void 0 ? "active-4xx-event" : "active-5xx-event";
|
|
24968
|
+
const statusLabel = input.trigger4xxStatus !== void 0 ? `${responseStatus}` : "5xx";
|
|
24882
24969
|
const verification = {
|
|
24883
|
-
mode:
|
|
24970
|
+
mode: activeMode,
|
|
24884
24971
|
bundle_status: "unknown",
|
|
24885
|
-
classification_reason: requestFailureReason()
|
|
24972
|
+
classification_reason: requestFailureReason(responseStatus)
|
|
24886
24973
|
};
|
|
24887
24974
|
const errors = [];
|
|
24888
24975
|
let exitCode = 0;
|
|
24889
24976
|
let tokenId = null;
|
|
24890
24977
|
let incidentId;
|
|
24891
|
-
let activeStep =
|
|
24978
|
+
let activeStep = activeCheckName;
|
|
24892
24979
|
try {
|
|
24893
24980
|
const token = await createProjectToken({
|
|
24894
24981
|
bearerToken: authState.bearer_token,
|
|
@@ -24902,7 +24989,8 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24902
24989
|
const event = buildCloudVerificationEvent({
|
|
24903
24990
|
now: verificationStartedAt,
|
|
24904
24991
|
serviceName,
|
|
24905
|
-
environment
|
|
24992
|
+
environment,
|
|
24993
|
+
responseStatus
|
|
24906
24994
|
});
|
|
24907
24995
|
const ingestion = await sendEvents({
|
|
24908
24996
|
baseUrl: authState.base_url,
|
|
@@ -24911,12 +24999,12 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24911
24999
|
});
|
|
24912
25000
|
verification.accepted_event_count = ingestion.accepted;
|
|
24913
25001
|
if (ingestion.accepted < 1 || ingestion.rejected > 0 || ingestion.errors.length > 0) {
|
|
24914
|
-
throw new Error(`Synthetic
|
|
25002
|
+
throw new Error(`Synthetic ${statusLabel} ingestion was not fully accepted: accepted=${ingestion.accepted}, rejected=${ingestion.rejected}.`);
|
|
24915
25003
|
}
|
|
24916
25004
|
checks.push({
|
|
24917
|
-
name:
|
|
25005
|
+
name: activeCheckName,
|
|
24918
25006
|
status: "ok",
|
|
24919
|
-
message:
|
|
25007
|
+
message: `Sent synthetic ${statusLabel} request_event through cloud ingestion.`
|
|
24920
25008
|
});
|
|
24921
25009
|
activeStep = "incident-retrieval";
|
|
24922
25010
|
for (let attempt = 1; attempt <= pollAttempts; attempt += 1) {
|
|
@@ -24934,7 +25022,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24934
25022
|
if (candidate !== void 0) {
|
|
24935
25023
|
incidentId = candidate.incident_id;
|
|
24936
25024
|
verification.incident_id = candidate.incident_id;
|
|
24937
|
-
verification.classification_reason = candidate.incident_reason ?? requestFailureReason();
|
|
25025
|
+
verification.classification_reason = candidate.incident_reason ?? requestFailureReason(responseStatus);
|
|
24938
25026
|
break;
|
|
24939
25027
|
}
|
|
24940
25028
|
if (attempt < pollAttempts) {
|
|
@@ -24942,12 +25030,12 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
24942
25030
|
}
|
|
24943
25031
|
}
|
|
24944
25032
|
if (incidentId === void 0) {
|
|
24945
|
-
throw new Error(
|
|
25033
|
+
throw new Error(`Synthetic ${statusLabel} request was accepted but no matching cloud incident was visible yet.`);
|
|
24946
25034
|
}
|
|
24947
25035
|
checks.push({
|
|
24948
25036
|
name: "incident-retrieval",
|
|
24949
25037
|
status: "ok",
|
|
24950
|
-
message: `Retrieved cloud incident ${incidentId} for the synthetic
|
|
25038
|
+
message: `Retrieved cloud incident ${incidentId} for the synthetic ${statusLabel} request.`
|
|
24951
25039
|
});
|
|
24952
25040
|
activeStep = "bundle-status";
|
|
24953
25041
|
const bundle = await getBundle({
|
|
@@ -25213,7 +25301,7 @@ var CLI_USAGE_LINES = [
|
|
|
25213
25301
|
" debugbundle clean [--events] [--bundles] [--all] [--older-than <Nd>] [--json]",
|
|
25214
25302
|
" debugbundle validate [--fix] [--json]",
|
|
25215
25303
|
" debugbundle verify local [--json]",
|
|
25216
|
-
" debugbundle verify cloud --project-id <id> [--trigger-5xx] [--service <name>] [--environment <name>] [--max-age-minutes <n>] [--auth-file <path>] [--json]",
|
|
25304
|
+
" debugbundle verify cloud --project-id <id> [--trigger-5xx | --trigger-4xx <400-499>] [--service <name>] [--environment <name>] [--max-age-minutes <n>] [--auth-file <path>] [--json]",
|
|
25217
25305
|
" debugbundle smoke --project-id <id> [--service <name>] [--environment <name>] [--max-age-minutes <n>] [--auth-file <path>] [--json]",
|
|
25218
25306
|
" debugbundle login [--base-url <url>] [--auth-file <path>] [--json]",
|
|
25219
25307
|
" debugbundle login <member-token> [--base-url <url>] [--auth-file <path>] [--json]",
|
|
@@ -25275,7 +25363,7 @@ var CLI_USAGE_LINES = [
|
|
|
25275
25363
|
" debugbundle weekly-report update <channel-id> [--day-of-week <day>] [--hour-of-day <0-23>] [--timezone <iana>] [--config-json <json>] [--is-enabled <true|false>] [--auth-file <path>] [--json]",
|
|
25276
25364
|
" debugbundle weekly-report delete <channel-id> [--auth-file <path>] [--json]",
|
|
25277
25365
|
" debugbundle capture-policy get --project <id> [--auth-file <path>] [--json]",
|
|
25278
|
-
" debugbundle capture-policy set --project <id> [--preset <minimal|balanced|investigative>] [--override <key=value>] [--auth-file <path>] [--json]",
|
|
25366
|
+
" debugbundle capture-policy set --project <id> [--preset <minimal|balanced|investigative>] [--override <key=value>] [--client-error-incidents <preset-default|none|recommended|custom>] [--client-error-statuses <400,401,...>] [--auth-file <path>] [--json]",
|
|
25279
25367
|
" debugbundle probe activate <project-id> --label-pattern <pattern> [--service <name>] [--environment <name>] [--ttl-seconds <n>] [--trigger-ttl-seconds <n>] [--auth-file <path>] [--json]",
|
|
25280
25368
|
" debugbundle probe list <project-id> [--auth-file <path>] [--json]",
|
|
25281
25369
|
" debugbundle probe deactivate <project-id> <activation-id> [--auth-file <path>] [--json]",
|
|
@@ -25942,16 +26030,6 @@ async function deleteAlertWithAuthCommand(input, dependencies) {
|
|
|
25942
26030
|
}
|
|
25943
26031
|
|
|
25944
26032
|
// src/capture-policy-commands.ts
|
|
25945
|
-
var ResolvedCapturePolicySchema = external_exports.object({
|
|
25946
|
-
preset: CapturePresetSchema,
|
|
25947
|
-
capture_logs: CaptureLogsSchema,
|
|
25948
|
-
capture_request_events: CaptureRequestEventsSchema,
|
|
25949
|
-
capture_breadcrumbs: CaptureBreadcrumbsSchema,
|
|
25950
|
-
capture_probe_events: CaptureProbeEventsSchema
|
|
25951
|
-
});
|
|
25952
|
-
var CapturePolicyResponseSchema = external_exports.object({
|
|
25953
|
-
policy: ResolvedCapturePolicySchema
|
|
25954
|
-
});
|
|
25955
26033
|
var CapturePolicyApiError = class extends Error {
|
|
25956
26034
|
status;
|
|
25957
26035
|
constructor(status, message) {
|
|
@@ -25981,7 +26059,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
25981
26059
|
if (!parsed.success) {
|
|
25982
26060
|
throw new CapturePolicyApiError(500, "Invalid capture policy response.");
|
|
25983
26061
|
}
|
|
25984
|
-
return parsed.data
|
|
26062
|
+
return parsed.data;
|
|
25985
26063
|
},
|
|
25986
26064
|
async updateCapturePolicy(input) {
|
|
25987
26065
|
const response = await httpClient.request({
|
|
@@ -25997,7 +26075,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
25997
26075
|
if (!parsed.success) {
|
|
25998
26076
|
throw new CapturePolicyApiError(500, "Invalid capture policy response.");
|
|
25999
26077
|
}
|
|
26000
|
-
return parsed.data
|
|
26078
|
+
return parsed.data;
|
|
26001
26079
|
}
|
|
26002
26080
|
};
|
|
26003
26081
|
}
|
|
@@ -26016,24 +26094,48 @@ function mapErrorToExitCode5(error) {
|
|
|
26016
26094
|
}
|
|
26017
26095
|
return 1;
|
|
26018
26096
|
}
|
|
26019
|
-
function
|
|
26097
|
+
function statusesEqual(left, right) {
|
|
26098
|
+
if (left.length !== right.length) {
|
|
26099
|
+
return false;
|
|
26100
|
+
}
|
|
26101
|
+
return left.every((value, index) => value === right[index]);
|
|
26102
|
+
}
|
|
26103
|
+
function formatStatusList(statuses) {
|
|
26104
|
+
return statuses.length === 0 ? "none" : statuses.join(", ");
|
|
26105
|
+
}
|
|
26106
|
+
function formatClientErrorIncidents(response) {
|
|
26107
|
+
const rawOverride = response.overrides.immediate_client_error_statuses;
|
|
26108
|
+
if (rawOverride === null) {
|
|
26109
|
+
return `preset default (${formatStatusList(response.policy.immediate_client_error_statuses)})`;
|
|
26110
|
+
}
|
|
26111
|
+
if (rawOverride.length === 0) {
|
|
26112
|
+
return "none (explicit)";
|
|
26113
|
+
}
|
|
26114
|
+
if (statusesEqual(rawOverride, RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES)) {
|
|
26115
|
+
return `recommended (${formatStatusList(rawOverride)})`;
|
|
26116
|
+
}
|
|
26117
|
+
return `custom (${formatStatusList(rawOverride)})`;
|
|
26118
|
+
}
|
|
26119
|
+
function formatPolicy(response) {
|
|
26120
|
+
const policy = response.policy;
|
|
26020
26121
|
return [
|
|
26021
26122
|
`preset: ${policy.preset}`,
|
|
26022
26123
|
`capture_logs: ${policy.capture_logs}`,
|
|
26023
26124
|
`capture_request_events: ${policy.capture_request_events}`,
|
|
26024
26125
|
`capture_breadcrumbs: ${policy.capture_breadcrumbs}`,
|
|
26025
|
-
`capture_probe_events: ${policy.capture_probe_events}
|
|
26126
|
+
`capture_probe_events: ${policy.capture_probe_events}`,
|
|
26127
|
+
`client_error_incidents: ${formatClientErrorIncidents(response)}`
|
|
26026
26128
|
].join("\n");
|
|
26027
26129
|
}
|
|
26028
26130
|
async function getCapturePolicyCommand(input, api) {
|
|
26029
26131
|
try {
|
|
26030
|
-
const
|
|
26132
|
+
const response = await api.getCapturePolicy({
|
|
26031
26133
|
bearerToken: input.bearerToken,
|
|
26032
26134
|
projectId: input.projectId
|
|
26033
26135
|
});
|
|
26034
26136
|
return {
|
|
26035
26137
|
exitCode: 0,
|
|
26036
|
-
output: input.json ? JSON.stringify(
|
|
26138
|
+
output: input.json ? JSON.stringify(response) : formatPolicy(response)
|
|
26037
26139
|
};
|
|
26038
26140
|
} catch (error) {
|
|
26039
26141
|
return {
|
|
@@ -26051,15 +26153,15 @@ async function setCapturePolicyCommand(input, api) {
|
|
|
26051
26153
|
output: "Invalid capture policy update."
|
|
26052
26154
|
};
|
|
26053
26155
|
}
|
|
26054
|
-
const
|
|
26156
|
+
const response = await api.updateCapturePolicy({
|
|
26055
26157
|
bearerToken: input.bearerToken,
|
|
26056
26158
|
projectId: input.projectId,
|
|
26057
26159
|
update: parsedUpdate.data
|
|
26058
26160
|
});
|
|
26059
26161
|
return {
|
|
26060
26162
|
exitCode: 0,
|
|
26061
|
-
output: input.json ? JSON.stringify(
|
|
26062
|
-
${formatPolicy(
|
|
26163
|
+
output: input.json ? JSON.stringify(response) : `Capture policy updated.
|
|
26164
|
+
${formatPolicy(response)}`
|
|
26063
26165
|
};
|
|
26064
26166
|
} catch (error) {
|
|
26065
26167
|
return {
|
|
@@ -28568,6 +28670,28 @@ async function handleTokenCommand(parsedArgv, dependencies) {
|
|
|
28568
28670
|
throw new CliInputError("Unknown token command.");
|
|
28569
28671
|
}
|
|
28570
28672
|
async function handleCapturePolicyCommand(parsedArgv, dependencies) {
|
|
28673
|
+
function parseClientErrorStatusesOption(value) {
|
|
28674
|
+
const parts = value.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
|
|
28675
|
+
if (parts.length === 0) {
|
|
28676
|
+
throw new CliInputError("Invalid value for --client-error-statuses.");
|
|
28677
|
+
}
|
|
28678
|
+
const statuses = [];
|
|
28679
|
+
for (const part of parts) {
|
|
28680
|
+
if (!/^\d+$/.test(part)) {
|
|
28681
|
+
throw new CliInputError("Invalid value for --client-error-statuses.");
|
|
28682
|
+
}
|
|
28683
|
+
const status = Number(part);
|
|
28684
|
+
if (!Number.isInteger(status) || status < 400 || status > 499) {
|
|
28685
|
+
throw new CliInputError("Invalid value for --client-error-statuses.");
|
|
28686
|
+
}
|
|
28687
|
+
statuses.push(status);
|
|
28688
|
+
}
|
|
28689
|
+
const normalized = Array.from(new Set(statuses)).sort((left, right) => left - right);
|
|
28690
|
+
if (normalized.length > 12) {
|
|
28691
|
+
throw new CliInputError("Invalid value for --client-error-statuses.");
|
|
28692
|
+
}
|
|
28693
|
+
return normalized;
|
|
28694
|
+
}
|
|
28571
28695
|
const action = requirePositional(parsedArgv, 1, "action");
|
|
28572
28696
|
if (action === "get") {
|
|
28573
28697
|
expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project"]);
|
|
@@ -28581,7 +28705,15 @@ async function handleCapturePolicyCommand(parsedArgv, dependencies) {
|
|
|
28581
28705
|
);
|
|
28582
28706
|
}
|
|
28583
28707
|
if (action === "set") {
|
|
28584
|
-
expectNoUnknownOptions(parsedArgv, [
|
|
28708
|
+
expectNoUnknownOptions(parsedArgv, [
|
|
28709
|
+
"auth-file",
|
|
28710
|
+
"json",
|
|
28711
|
+
"project",
|
|
28712
|
+
"preset",
|
|
28713
|
+
"override",
|
|
28714
|
+
"client-error-incidents",
|
|
28715
|
+
"client-error-statuses"
|
|
28716
|
+
]);
|
|
28585
28717
|
ensureNoExtraPositionals(parsedArgv, 2);
|
|
28586
28718
|
const projectId = readStringOption(parsedArgv, "project");
|
|
28587
28719
|
if (projectId === void 0) {
|
|
@@ -28605,6 +28737,32 @@ async function handleCapturePolicyCommand(parsedArgv, dependencies) {
|
|
|
28605
28737
|
}
|
|
28606
28738
|
update[key] = rawValue === "null" ? null : rawValue;
|
|
28607
28739
|
}
|
|
28740
|
+
const clientErrorIncidents = readStringOption(parsedArgv, "client-error-incidents");
|
|
28741
|
+
const clientErrorStatuses = readStringOption(parsedArgv, "client-error-statuses");
|
|
28742
|
+
if (clientErrorStatuses !== void 0 && clientErrorIncidents !== "custom") {
|
|
28743
|
+
throw new CliInputError("Use --client-error-statuses only with --client-error-incidents custom.");
|
|
28744
|
+
}
|
|
28745
|
+
if (clientErrorIncidents !== void 0) {
|
|
28746
|
+
switch (clientErrorIncidents) {
|
|
28747
|
+
case "preset-default":
|
|
28748
|
+
update.immediate_client_error_statuses = null;
|
|
28749
|
+
break;
|
|
28750
|
+
case "none":
|
|
28751
|
+
update.immediate_client_error_statuses = [];
|
|
28752
|
+
break;
|
|
28753
|
+
case "recommended":
|
|
28754
|
+
update.immediate_client_error_statuses = [...RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES];
|
|
28755
|
+
break;
|
|
28756
|
+
case "custom":
|
|
28757
|
+
if (clientErrorStatuses === void 0) {
|
|
28758
|
+
throw new CliInputError("Missing required option --client-error-statuses.");
|
|
28759
|
+
}
|
|
28760
|
+
update.immediate_client_error_statuses = parseClientErrorStatusesOption(clientErrorStatuses);
|
|
28761
|
+
break;
|
|
28762
|
+
default:
|
|
28763
|
+
throw new CliInputError("Invalid value for --client-error-incidents.");
|
|
28764
|
+
}
|
|
28765
|
+
}
|
|
28608
28766
|
if (Object.keys(update).length === 0) {
|
|
28609
28767
|
throw new CliInputError("At least one capture policy field must be provided.");
|
|
28610
28768
|
}
|
|
@@ -29389,7 +29547,7 @@ ${formatUsage()}`
|
|
|
29389
29547
|
return await (dependencies.verifyLocalCommand ?? verifyLocalCommand)(readBooleanOption(parsedArgv, "json") === true ? { json: true } : {});
|
|
29390
29548
|
}
|
|
29391
29549
|
if (subcommand === "cloud") {
|
|
29392
|
-
expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id", "service", "environment", "max-age-minutes", "trigger-5xx"]);
|
|
29550
|
+
expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id", "service", "environment", "max-age-minutes", "trigger-5xx", "trigger-4xx"]);
|
|
29393
29551
|
ensureNoExtraPositionals(parsedArgv, 2);
|
|
29394
29552
|
const projectId = readStringOption(parsedArgv, "project-id");
|
|
29395
29553
|
if (projectId === void 0) {
|
|
@@ -29407,6 +29565,10 @@ ${formatUsage()}`
|
|
|
29407
29565
|
if (readBooleanOption(parsedArgv, "trigger-5xx") === true) {
|
|
29408
29566
|
input.trigger5xx = true;
|
|
29409
29567
|
}
|
|
29568
|
+
const trigger4xxStatus = readIntegerOption(parsedArgv, "trigger-4xx");
|
|
29569
|
+
if (trigger4xxStatus !== void 0) {
|
|
29570
|
+
input.trigger4xxStatus = trigger4xxStatus;
|
|
29571
|
+
}
|
|
29410
29572
|
return await (dependencies.verifyCloudCommand ?? verifyCloudCommand)(input);
|
|
29411
29573
|
}
|
|
29412
29574
|
throw new CliInputError("Unknown verify command.");
|