@@ -4,7 +4,7 @@ import envPaths from "env-paths";
44import psList , { ProcessDescriptor } from "@trufflesuite/ps-list" ;
55import { Dirent , promises as fsPromises } from "fs" ;
66// this awkward import is required to support node 12
7- const { readFile, rm, mkdir, readdir, writeFile } = fsPromises ;
7+ const { readFile, rm, mkdir, readdir, writeFile, unlink } = fsPromises ;
88import path from "path" ;
99import { FlavorName } from "@ganache/flavors" ;
1010
@@ -204,6 +204,7 @@ export async function startDetachedInstance(
204204export async function getDetachedInstances ( ) : Promise < DetachedInstance [ ] > {
205205 let dirEntries : Dirent [ ] ;
206206 let processes : ProcessDescriptor [ ] ;
207+ let someInstancesFailed = false ;
207208
208209 try {
209210 [ dirEntries , processes ] = await Promise . all ( [
@@ -220,52 +221,70 @@ export async function getDetachedInstances(): Promise<DetachedInstance[]> {
220221 const instances : DetachedInstance [ ] = [ ] ;
221222
222223 const loadingInstancesInfos = dirEntries . map ( async dirEntry => {
223- const { name : instanceName , ext } = path . parse ( dirEntry . name ) ;
224+ const filename = dirEntry . name ;
225+ const { name : instanceName , ext } = path . parse ( filename ) ;
224226
225- if ( dirEntry . isDirectory ( ) || ext !== ".json" ) {
226- try {
227- rm ( path . join ( dataPath , dirEntry . name ) , { recursive : true } ) ;
228- console . warn ( `Invalid instance file found; ${ dirEntry . name } removed.` ) ;
229- } catch {
230- console . warn (
231- `Invalid instance file found; ${ dirEntry . name } could not be removed.`
232- ) ;
233- }
227+ let failureReason : string ;
228+
229+ if ( ext !== ".json" ) {
230+ failureReason = `"${ filename } " does not have a .json extension` ;
234231 } else {
235- let shouldRemoveInstance = false ;
232+ let instance : DetachedInstance ;
236233 try {
237234 // getDetachedInstanceByName() throws if the instance file is not found or
238235 // cannot be parsed
239- const instance = await getDetachedInstanceByName ( instanceName ) ;
240-
236+ instance = await getDetachedInstanceByName ( instanceName ) ;
237+ } catch ( err : any ) {
238+ failureReason = err . message ;
239+ }
240+ if ( instance ) {
241241 const matchingProcess = processes . find ( p => p . pid === instance . pid ) ;
242242 if ( ! matchingProcess ) {
243- console . warn (
244- `Process with PID ${ instance . pid } could not be found; removing ${ instanceName } from recorded instances.`
245- ) ;
246- shouldRemoveInstance = true ;
243+ failureReason = `Process with PID ${ instance . pid } could not be found` ;
247244 } else if ( matchingProcess . cmd !== instance . cmd ) {
248- // if the cmd does not match the instance, the process has been killed,
249- // and another application has taken the pid
250- console . warn (
251- `Process with PID ${ instance . pid } doesn't match ${ instanceName } ; removing${ instanceName } from recorded instances.`
252- ) ;
253- shouldRemoveInstance = true ;
245+ failureReason = `Process with PID ${ instance . pid } does not match ${ instanceName } ` ;
254246 } else {
255247 instances . push ( instance ) ;
256248 }
257- } catch {
258- console . warn (
259- `Failed to load instance data; ${ instanceName } has been removed.`
260- ) ;
261- shouldRemoveInstance = true ;
262249 }
263- if ( shouldRemoveInstance ) await removeDetachedInstanceFile ( instanceName ) ;
250+ }
251+
252+ if ( failureReason !== undefined ) {
253+ someInstancesFailed = true ;
254+ const fullPath = path . join ( dataPath , filename ) ;
255+ let resolution : string ;
256+ if ( dirEntry . isDirectory ( ) ) {
257+ const reason = `"${ filename } " is a directory` ;
258+ try {
259+ await rm ( fullPath , { recursive : true } ) ;
260+ failureReason = reason ;
261+ } catch {
262+ resolution = `"${ filename } " could not be removed` ;
263+ }
264+ } else {
265+ try {
266+ await unlink ( fullPath ) ;
267+ } catch {
268+ resolution = `"${ filename } " could not be removed` ;
269+ }
270+ }
271+
272+ console . warn (
273+ `Failed to load instance data. ${ failureReason } . ${
274+ resolution || `"${ filename } " has been removed`
275+ } .`
276+ ) ;
264277 }
265278 } ) ;
266279
267280 await Promise . all ( loadingInstancesInfos ) ;
268281
282+ if ( someInstancesFailed ) {
283+ console . warn (
284+ "If this keeps happening, please open an issue at https://github.com/trufflesuite/ganache/issues/new\n"
285+ ) ;
286+ }
287+
269288 return instances ;
270289}
271290
0 commit comments