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