@@ -94,24 +94,34 @@ async function startIpfsWithLogs (ipfsd) {
94
94
let isMigrating , isErrored , isFinished
95
95
let logs = ''
96
96
97
+ const isSpawnedDaemonDead = ( ipfsd ) => {
98
+ if ( typeof ipfsd . subprocess === 'undefined' ) throw new Error ( 'missing ipfsd.subprocess, unable to reason about startup errors' )
99
+ if ( ipfsd . subprocess === null ) return false // not spawned yet
100
+ if ( ipfsd . subprocess ?. failed ) return true // explicit failure
101
+
102
+ // detect when spawned ipfsd process is gone/dead
103
+ // by inspecting its pid - it should be alive
104
+ const { pid } = ipfsd . subprocess
105
+ try {
106
+ // signal 0 throws if process is missing, noop otherwise
107
+ process . kill ( pid , 0 )
108
+ return false
109
+ } catch ( e ) {
110
+ return true
111
+ }
112
+ }
113
+
97
114
const stopListening = listenToIpfsLogs ( ipfsd , data => {
98
115
logs += data . toString ( )
99
116
const line = data . toLowerCase ( )
100
117
isMigrating = isMigrating || line . includes ( 'migration' )
101
- isErrored = isErrored || line . includes ( 'error' )
118
+ isErrored = isErrored || isSpawnedDaemonDead ( ipfsd )
102
119
isFinished = isFinished || line . includes ( 'daemon is ready' )
103
120
104
- if ( ! isMigrating ) {
121
+ if ( ! isMigrating && ! isErrored ) {
105
122
return
106
123
}
107
124
108
- // Undo error state if retrying after HTTP failure
109
- // https://github.com/ipfs/ipfs-desktop/issues/2003
110
- if ( isErrored && line . includes ( 'fetching with ipfs' ) && ! line . includes ( 'error' ) ) {
111
- isErrored = false
112
- if ( migrationPrompt ) migrationPrompt . loadWindow ( logs , isErrored , isFinished )
113
- }
114
-
115
125
if ( ! migrationPrompt ) {
116
126
logger . info ( '[daemon] ipfs data store is migrating' )
117
127
migrationPrompt = showMigrationPrompt ( logs , isErrored , isFinished )
@@ -134,10 +144,20 @@ async function startIpfsWithLogs (ipfsd) {
134
144
} catch ( e ) {
135
145
err = e
136
146
} finally {
137
- // stop monitoring daemon output - we only care about migration phase
147
+ // stop monitoring daemon output - we only care about startup phase
138
148
stopListening ( )
149
+
150
+ // Show startup error using the same UI as migrations.
151
+ // This is catch-all that will show stdout/stderr of ipfs daemon
152
+ // that failed to start, allowing user to self-diagnose or report issue.
153
+ isErrored = isErrored || isSpawnedDaemonDead ( ipfsd )
139
154
if ( isErrored ) { // save daemon output to error.log
140
155
logger . error ( logs )
156
+ if ( migrationPrompt ) {
157
+ migrationPrompt . loadWindow ( logs , isErrored , isFinished )
158
+ } else {
159
+ showMigrationPrompt ( logs , isErrored , isFinished )
160
+ }
141
161
}
142
162
}
143
163
0 commit comments