11import * as Debug from "debug" ;
22import { mkdir , mkdtemp , rm , stat , writeFile } from "fs/promises" ;
3+ import * as os from "os" ;
34import * as path from "path" ;
5+ import { getErrorMessage } from "../../error-utils" ;
46import { FilePathToContent , FilesByDirMap } from "./types" ;
57const debug = Debug ( "snyk" ) ;
68
@@ -22,7 +24,7 @@ interface ScanPaths {
2224async function createTempProjectDir (
2325 projectDir : string ,
2426) : Promise < { tmpDir : string ; tempProjectRoot : string } > {
25- const tmpDir = await mkdtemp ( "snyk" ) ;
27+ const tmpDir = await mkdtemp ( path . join ( os . tmpdir ( ) , "snyk-" ) ) ;
2628
2729 const tempProjectRoot = path . join ( tmpDir , projectDir ) ;
2830
@@ -51,7 +53,9 @@ async function createSyntheticManifest(
5153 await writeFile ( tempRootManifestPath , "{}" , "utf-8" ) ;
5254 } catch ( error ) {
5355 debug (
54- `Error while writing file ${ tempRootManifestPath } : ${ error . message } ` ,
56+ `Error while writing file ${ tempRootManifestPath } : ${ getErrorMessage (
57+ error ,
58+ ) } `,
5559 ) ;
5660 }
5761}
@@ -76,20 +80,23 @@ async function persistNodeModules(
7680 fileNamesGroupedByDirectory : FilesByDirMap ,
7781) : Promise < ScanPaths > {
7882 const modules = fileNamesGroupedByDirectory . get ( project ) ;
79- const tmpDir : string = "" ;
80- const tempProjectRoot : string = "" ;
8183
8284 if ( ! modules || modules . size === 0 ) {
8385 debug ( `Empty application directory tree.` ) ;
84-
85- return {
86- tempDir : tmpDir ,
87- tempProjectPath : tempProjectRoot ,
88- } ;
86+ return { tempDir : "" , tempProjectPath : "" } ;
8987 }
9088
89+ // Create the temp directory first so we can return it in the catch block
90+ // for cleanup. Previously, the outer tmpDir/tempProjectRoot were always
91+ // empty strings, meaning any temp directory created before a failure in
92+ // saveOnDisk or later steps would be leaked (caller couldn't clean it up).
93+ let tmpDir = "" ;
94+ let tempProjectRoot = "" ;
95+
9196 try {
92- const { tmpDir, tempProjectRoot } = await createTempProjectDir ( project ) ;
97+ const created = await createTempProjectDir ( project ) ;
98+ tmpDir = created . tmpDir ;
99+ tempProjectRoot = created . tempProjectRoot ;
93100
94101 await saveOnDisk ( tmpDir , modules , filePathToContent ) ;
95102
@@ -113,7 +120,9 @@ async function persistNodeModules(
113120 return result ;
114121 } catch ( error ) {
115122 debug (
116- `Failed to copy the application manifest files locally: ${ error . message } ` ,
123+ `Failed to copy the application manifest files locally: ${ getErrorMessage (
124+ error ,
125+ ) } `,
117126 ) ;
118127 return {
119128 tempDir : tmpDir ,
@@ -122,12 +131,15 @@ async function persistNodeModules(
122131 }
123132}
124133
125- async function createFile ( filePath , fileContent ) : Promise < void > {
134+ async function createFile (
135+ filePath : string ,
136+ fileContent : string ,
137+ ) : Promise < void > {
126138 try {
127139 await mkdir ( path . dirname ( filePath ) , { recursive : true } ) ;
128140 await writeFile ( filePath , fileContent , "utf-8" ) ;
129141 } catch ( error ) {
130- debug ( `Error while creating file ${ filePath } : ${ error . message } ` ) ;
142+ debug ( `Error while creating file ${ filePath } : ${ getErrorMessage ( error ) } ` ) ;
131143 }
132144}
133145
@@ -241,6 +253,6 @@ async function cleanupAppNodeModules(appRootDir: string): Promise<void> {
241253 try {
242254 await rm ( appRootDir , { recursive : true } ) ;
243255 } catch ( error ) {
244- debug ( `Error while removing ${ appRootDir } : ${ error . message } ` ) ;
256+ debug ( `Error while removing ${ appRootDir } : ${ getErrorMessage ( error ) } ` ) ;
245257 }
246258}
0 commit comments