@@ -10,6 +10,7 @@ import {
1010import {
1111 collectTelemetryExport ,
1212 type ExportRequest ,
13+ type ExportResult ,
1314 type ExportRuntime ,
1415} from "./pipeline" ;
1516import { promptForExport , type ExportChoice } from "./prompts" ;
@@ -21,8 +22,6 @@ import type { FlushStatus } from "../service";
2122
2223import type { ExportFormat } from "./writers/types" ;
2324
24- const REVEAL_ACTION = "Reveal in File Explorer" ;
25-
2625const PROGRESS_OPTIONS = {
2726 location : vscode . ProgressLocation . Notification ,
2827 title : "Exporting Coder telemetry" ,
@@ -36,7 +35,7 @@ const PROGRESS_OPTIONS = {
3635export interface ExportTelemetryObserver {
3736 abort ( stage : "prompt" | "progress" ) : void ;
3837 error ( ) : void ;
39- succeedExport ( format : ExportFormat , eventCount : number ) : void ;
38+ succeedExport ( format : ExportFormat , result : ExportResult ) : void ;
4039}
4140
4241export async function runExportTelemetryCommand (
@@ -87,12 +86,15 @@ function exportRuntime(
8786 ) ,
8887 onCleanupError : ( err , target ) =>
8988 logger . warn ( "Failed to clean up after telemetry export" , target , err ) ,
89+ // The skipped file's name and line are in the error message.
90+ onFileSkipped : ( err ) =>
91+ logger . warn ( "Telemetry export skipped an unreadable file" , err ) ,
9092 } ;
9193}
9294
9395/** Turns the export result into the matching user-facing notification. */
9496async function reportOutcome (
95- result : ProgressResult < number > ,
97+ result : ProgressResult < ExportResult > ,
9698 choice : ExportChoice ,
9799 logger : Logger ,
98100 observer : ExportTelemetryObserver ,
@@ -110,29 +112,59 @@ async function reportOutcome(
110112 return ;
111113 }
112114
113- const eventCount = result . value ;
114- observer . succeedExport ( choice . format , eventCount ) ;
115+ const { eventCount, skippedFileCount } = result . value ;
116+ observer . succeedExport ( choice . format , result . value ) ;
115117 if ( eventCount === 0 ) {
116- void vscode . window . showInformationMessage (
118+ void showExportMessage (
117119 `No telemetry events found for ${ choice . range . label } .` ,
120+ skippedFileCount ,
121+ logger ,
118122 ) ;
119123 return ;
120124 }
121- await notifyExportSucceeded ( choice . outputPath , eventCount , logger ) ;
125+ const action = await showExportMessage (
126+ `Exported ${ formatEventCount ( eventCount ) } to ${ choice . outputPath } .` ,
127+ skippedFileCount ,
128+ logger ,
129+ "Reveal in File Explorer" ,
130+ ) ;
131+ if ( action === "Reveal in File Explorer" ) {
132+ await revealExportedFile ( choice . outputPath , logger ) ;
133+ }
122134}
123135
124- async function notifyExportSucceeded (
125- outputPath : string ,
126- eventCount : number ,
136+ type ExportAction = "Reveal in File Explorer" ;
137+
138+ /**
139+ * A partial export warns and names the unreadable-file count. "Show Output"
140+ * is offered on warnings and handled here; only caller actions are returned.
141+ */
142+ async function showExportMessage (
143+ message : string ,
144+ skippedFileCount : number ,
127145 logger : Logger ,
128- ) : Promise < void > {
129- const action = await vscode . window . showInformationMessage (
130- `Exported ${ formatEventCount ( eventCount ) } to ${ outputPath } .` ,
131- REVEAL_ACTION ,
146+ ...actions : ExportAction [ ]
147+ ) : Promise < ExportAction | undefined > {
148+ if ( skippedFileCount === 0 ) {
149+ return vscode . window . showInformationMessage ( message , ...actions ) ;
150+ }
151+ const files = skippedFileCount === 1 ? "file" : "files" ;
152+ const action = await vscode . window . showWarningMessage (
153+ `${ message } ${ skippedFileCount } ${ files } could not be read. Check the Coder output for details.` ,
154+ ...actions ,
155+ "Show Output" ,
132156 ) ;
133- if ( action !== REVEAL_ACTION ) {
134- return ;
157+ if ( action === "Show Output" ) {
158+ logger . show ( ) ;
159+ return undefined ;
135160 }
161+ return action ;
162+ }
163+
164+ async function revealExportedFile (
165+ outputPath : string ,
166+ logger : Logger ,
167+ ) : Promise < void > {
136168 try {
137169 await vscode . commands . executeCommand (
138170 "revealFileInOS" ,
0 commit comments