@@ -4,50 +4,51 @@ import { isKeyringEnabled } from "../settings/cli";
44import type { WorkspaceConfiguration } from "vscode" ;
55
66import type { TelemetryReporter } from "../telemetry/reporter" ;
7+ import type { Span } from "../telemetry/span" ;
78
89export type CredentialCategory = "keyring" | "file" ;
910export type CredentialFailureCategory = "aborted" | "binary" | "cli" | "file" ;
1011
11- export interface CredentialStoreResult {
12- readonly category : CredentialCategory ;
12+ export interface CredentialStoreRecorder {
13+ setCategory ( category : CredentialCategory ) : void ;
14+ }
15+
16+ export interface CredentialClearRecorder {
17+ setCategory ( category : CredentialCategory ) : void ;
1318}
1419
1520export interface CredentialClearResult {
16- readonly category : CredentialCategory ;
1721 readonly failureCategory ?: CredentialFailureCategory ;
1822}
1923
2024export class CredentialTelemetry {
2125 public constructor ( private readonly telemetry : TelemetryReporter ) { }
2226
23- public async traceStore < T extends CredentialStoreResult > (
27+ public async traceStore < T > (
2428 configs : Pick < WorkspaceConfiguration , "get" > ,
25- fn : ( ) => Promise < T > ,
29+ fn : ( recorder : CredentialStoreRecorder ) => Promise < T > ,
2630 ) : Promise < T > {
27- const keyringEnabled = isKeyringEnabled ( configs ) ;
28- const defaultCategory : CredentialCategory = keyringEnabled
29- ? "keyring"
30- : "file" ;
31+ const defaults = defaultCredentialProperties ( configs ) ;
3132 let cancellation : unknown ;
3233 const result = await this . telemetry . trace (
33- "auth.credential_stored " ,
34+ "auth.credential.store " ,
3435 async ( span ) => {
3536 try {
36- const result = await fn ( ) ;
37- span . setProperty ( "category" , result . category ) ;
38- return result ;
37+ return await fn ( createCredentialRecorder ( span ) ) ;
3938 } catch ( error ) {
40- span . setProperty ( "category" , defaultCategory ) ;
41- span . setProperty ( "failureCategory" , categorizeCredentialError ( error ) ) ;
39+ recordCredentialFailure ( span , defaults . category , error ) ;
4240 if ( isAbortError ( error ) ) {
4341 span . markAborted ( ) ;
4442 cancellation = error ;
45- return { category : defaultCategory } as T ;
43+ return undefined as T ;
4644 }
4745 throw error ;
4846 }
4947 } ,
50- { keyringEnabled, category : defaultCategory } ,
48+ {
49+ keyring_enabled : defaults . keyringEnabled ,
50+ category : defaults . category ,
51+ } ,
5152 ) ;
5253 if ( cancellation instanceof Error ) {
5354 throw cancellation ;
@@ -57,43 +58,31 @@ export class CredentialTelemetry {
5758
5859 public async traceClear < T extends CredentialClearResult > (
5960 configs : Pick < WorkspaceConfiguration , "get" > ,
60- fn : ( ) => Promise < T > ,
61+ fn : ( recorder : CredentialClearRecorder ) => Promise < T > ,
6162 ) : Promise < T > {
62- const keyringEnabled = isKeyringEnabled ( configs ) ;
63- const defaultCategory : CredentialCategory = keyringEnabled
64- ? "keyring"
65- : "file" ;
63+ const defaults = defaultCredentialProperties ( configs ) ;
6664 let cancellation : unknown ;
6765 const result = await this . telemetry . trace (
68- "auth.credential_cleared " ,
66+ "auth.credential.clear " ,
6967 async ( span ) => {
7068 try {
71- const result = await fn ( ) ;
72- span . setProperty ( "category" , result . category ) ;
73- if ( result . failureCategory ) {
74- span . setProperty ( "failureCategory" , result . failureCategory ) ;
75- if ( result . failureCategory === "aborted" ) {
76- span . markAborted ( ) ;
77- } else {
78- span . markFailure ( ) ;
79- }
80- }
69+ const result = await fn ( createCredentialRecorder ( span ) ) ;
70+ recordClearFailure ( span , result . failureCategory ) ;
8171 return result ;
8272 } catch ( error ) {
83- span . setProperty ( "category" , defaultCategory ) ;
84- span . setProperty ( "failureCategory" , categorizeCredentialError ( error ) ) ;
73+ recordCredentialFailure ( span , defaults . category , error ) ;
8574 if ( isAbortError ( error ) ) {
8675 span . markAborted ( ) ;
8776 cancellation = error ;
88- return {
89- category : defaultCategory ,
90- failureCategory : "aborted" ,
91- } as T ;
77+ return { failureCategory : "aborted" } as T ;
9278 }
9379 throw error ;
9480 }
9581 } ,
96- { keyringEnabled, category : defaultCategory } ,
82+ {
83+ keyring_enabled : defaults . keyringEnabled ,
84+ category : defaults . category ,
85+ } ,
9786 ) ;
9887 if ( cancellation instanceof Error ) {
9988 throw cancellation ;
@@ -102,6 +91,49 @@ export class CredentialTelemetry {
10291 }
10392}
10493
94+ function defaultCredentialProperties (
95+ configs : Pick < WorkspaceConfiguration , "get" > ,
96+ ) : { keyringEnabled : boolean ; category : CredentialCategory } {
97+ const keyringEnabled = isKeyringEnabled ( configs ) ;
98+ return {
99+ keyringEnabled,
100+ category : keyringEnabled ? "keyring" : "file" ,
101+ } ;
102+ }
103+
104+ function createCredentialRecorder (
105+ span : Span ,
106+ ) : CredentialStoreRecorder & CredentialClearRecorder {
107+ return {
108+ setCategory : ( category ) => span . setProperty ( "category" , category ) ,
109+ } ;
110+ }
111+
112+ function recordCredentialFailure (
113+ span : Span ,
114+ category : CredentialCategory ,
115+ error : unknown ,
116+ ) : void {
117+ span . setProperty ( "category" , category ) ;
118+ span . setProperty ( "failure_category" , categorizeCredentialError ( error ) ) ;
119+ }
120+
121+ function recordClearFailure (
122+ span : Span ,
123+ failureCategory : CredentialClearResult [ "failureCategory" ] ,
124+ ) : void {
125+ if ( ! failureCategory ) {
126+ return ;
127+ }
128+
129+ span . setProperty ( "failure_category" , failureCategory ) ;
130+ if ( failureCategory === "aborted" ) {
131+ span . markAborted ( ) ;
132+ return ;
133+ }
134+ span . markFailure ( ) ;
135+ }
136+
105137export function categorizeCredentialError (
106138 error : unknown ,
107139) : CredentialFailureCategory {
0 commit comments