Skip to content

Commit 5b48782

Browse files
committed
fix: finally retrying generate manifest until it succeds
Instead of trying different hacks to defer `executeInstructions` and `generateManifest` calls. We now retry the `generateManifest` for multiple times only when the error points to a malformed JSON.
1 parent b73e095 commit 5b48782

File tree

2 files changed

+34
-36
lines changed

2 files changed

+34
-36
lines changed

commands/Invoke.ts

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77
* file that was distributed with this source code.
88
*/
99

10-
import { open } from 'fs-extra'
11-
import { join } from 'path'
1210
import { BaseCommand, args } from '@adonisjs/ace'
1311

1412
import { Manifest } from '../src/Manifest'
15-
import { ADONIS_ACE_CWD, ADONIS_BUILD_DIR } from '../config/env'
13+
import { ADONIS_ACE_CWD } from '../config/env'
1614

1715
/**
1816
* Invoke post install instructions
@@ -27,33 +25,6 @@ export default class Invoke extends BaseCommand {
2725
@args.string({ description: 'Name of the package for which to invoke post install instructions' })
2826
public name: string
2927

30-
/**
31-
* Attempts to access the rc file handling the race condition of
32-
* it's being accessed by another process.
33-
*/
34-
private async accessRcFile (counter = 0) {
35-
const buildDir = ADONIS_BUILD_DIR()
36-
const cwd = ADONIS_ACE_CWD()!
37-
38-
/**
39-
* Return early when we are unaware of the build
40-
* directory
41-
*/
42-
if (!buildDir) {
43-
return
44-
}
45-
46-
try {
47-
await open(join(cwd, buildDir, '.adonisrc.json'), 'r+')
48-
} catch (error) {
49-
if (error.code === 'EBUSY' && counter < 3) {
50-
await this.accessRcFile(counter + 1)
51-
} else {
52-
throw error
53-
}
54-
}
55-
}
56-
5728
/**
5829
* Invoked automatically by ace
5930
*/
@@ -73,12 +44,6 @@ export default class Invoke extends BaseCommand {
7344

7445
const { executeInstructions } = await import('@adonisjs/sink')
7546
await executeInstructions(this.name, cwd, this.application)
76-
77-
try {
78-
await this.accessRcFile()
79-
} catch (error) {
80-
}
81-
8247
await new Manifest(cwd, this.logger).generate()
8348
}
8449
}

src/Manifest/index.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,30 @@ const WARN_MESSAGE = [
1919
* Exposes the API to execute generate manifest file
2020
*/
2121
export class Manifest {
22+
/**
23+
* The maximum number of times we should attempt to generate
24+
* the manifest file before giving up.
25+
*
26+
* This number make sound too big, but in real world scanerio, we
27+
* have seen encountered malformed JSON between 10-12 times.
28+
*
29+
* The JSON gets malformed, when a parallel process (node ace serve --watch)
30+
* is trying to update it.
31+
*/
32+
private maxAttempts = 15
33+
private attempts = 0
34+
2235
constructor (private appRoot: string, private logger: Logger) {
2336
}
2437

38+
/**
39+
* Returns a boolean telling if the error message is pointing
40+
* towards invalid or empty JSON file read attempt.
41+
*/
42+
private isMalformedJSONError (error: string) {
43+
return error.includes('Unexpected end of JSON input')
44+
}
45+
2546
/**
2647
* Generates the manifest file. We ignore `generate:manifest` errors for
2748
* now, since it's a secondary task for us and one should run it
@@ -41,6 +62,12 @@ export class Manifest {
4162
* Print warning when `stderr` exists
4263
*/
4364
if (response.stderr) {
65+
if (this.isMalformedJSONError(response.stderr) && this.attempts < this.maxAttempts) {
66+
this.attempts++
67+
await this.generate()
68+
return
69+
}
70+
4471
this.logger.warn(WARN_MESSAGE)
4572
this.logger.fatal({
4673
message: response.stderr,
@@ -56,6 +83,12 @@ export class Manifest {
5683
console.log(response.stdout)
5784
}
5885
} catch (error) {
86+
if (this.isMalformedJSONError(error.stderr) && this.attempts < this.maxAttempts) {
87+
this.attempts++
88+
await this.generate()
89+
return
90+
}
91+
5992
/**
6093
* Print warning on error
6194
*/

0 commit comments

Comments
 (0)