Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch and print docker build errors #1499

Merged
merged 2 commits into from
Oct 19, 2022
Merged

Catch and print docker build errors #1499

merged 2 commits into from
Oct 19, 2022

Conversation

dcroote
Copy link
Contributor

@dcroote dcroote commented Oct 15, 2022

Closes #1493.

Using throw within NODE_OPTIONS='--unhandled-rejections=throw' as this is the default for node v15.0.0 and above.

I tested this by inserting exit 1 before the airnode-admin docker build command. Without this PR's change, the build "succeeds" despite the error, which reproduces the previous behavior:

Running command: 'exit 1; docker build --no-cache --build-arg npmRegistryUrl=http://172.17.0.3:4873 --build-arg npmTag=local --tag api3/airnode-admin-dev:local --file packages/airnode-admin/docker/Dockerfile packa
ges/airnode-admin/docker'
(node:1081) UnhandledPromiseRejectionWarning: Error: Command failed: exit 1; docker build --no-cache --build-arg npmRegistryUrl=http://172.17.0.3:4873 --build-arg npmTag=local --tag api3/airnode-admin-dev:local --
file packages/airnode-admin/docker/Dockerfile packages/airnode-admin/docker
    at checkExecSyncError (child_process.js:790:11)
    at execSync (child_process.js:863:15)
    at runCommand (/build/docker/scripts/utils.ts:7:18)
    at buildContainers (/build/docker/scripts/prepare-containers.ts:57:13)
    at /build/docker/scripts/prepare-containers.ts:71:3
    at Generator.next (<anonymous>)
    at fulfilled (/build/docker/scripts/prepare-containers.ts:11:58)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:1081) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handle
d with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 5
)
(node:1081) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 61.04s.

With this PR's change, the process exits as desired, and there are stdout and stderr outputs, which I think suffices for our purposes (rather than needing everything streamed).

Running command: 'exit 1; docker build --no-cache --build-arg npmRegistryUrl=http://172.17.0.5:4873 --build-arg npmTag=local --tag api3/airnode-admin-dev:local --file packages/airnode-admin/docker/Dockerfile packa
ges/airnode-admin/docker'
Error: Command failed: exit 1; docker build --no-cache --build-arg npmRegistryUrl=http://172.17.0.5:4873 --build-arg npmTag=local --tag api3/airnode-admin-dev:local --file packages/airnode-admin/docker/Dockerfile
packages/airnode-admin/docker
    at checkExecSyncError (child_process.js:790:11)
    at execSync (child_process.js:863:15)
    at runCommand (/build/docker/scripts/utils.ts:7:18)
    at buildContainers (/build/docker/scripts/prepare-containers.ts:57:13)
    at /build/docker/scripts/prepare-containers.ts:71:3
    at Generator.next (<anonymous>)
    at fulfilled (/build/docker/scripts/prepare-containers.ts:11:58)
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  status: 1,
  signal: null,
  output: [ null, Buffer(0) [Uint8Array] [], Buffer(0) [Uint8Array] [] ],
  pid: 1394,
  stdout: Buffer(0) [Uint8Array] [],
  stderr: Buffer(0) [Uint8Array] []
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Copy link
Contributor

@Siegrift Siegrift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LGTM.

Maybe add a comment to remove that once we upgrade to node16? #1457

Copy link
Contributor

@aquarat aquarat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A [Uint8Array] output will be unreadable though?
The original task asks to be able to see the output from underlying docker image builds. The reason we don't see that currently AFAIK is because a throw occurs before the printing to the terminal of the output of stdout and stderr - so you could move the throw a few lines and then you will get the stderr/stdout output?

This is what the output with this PR would look like (in terms of the handling of stderr/stdout:

> child_process.spawnSync('bash', [`-c "echo testing; exit 1"`])
{
  status: 2,
  signal: null,
  output: [
    null,
    <Buffer >,
    <Buffer 62 61 73 68 3a 20 2d 20 3a 20 69 6e 76 61 6c 69 64 20 6f 70 74 69 6f 6e 0a 55 73 61 67 65 3a 09 62 61 73 68 20 5b 47 4e 55 20 6c 6f 6e 67 20 6f 70 74 ... 384 more bytes>
  ],
  pid: 65063,
  stdout: <Buffer >,
  stderr: <Buffer 62 61 73 68 3a 20 2d 20 3a 20 69 6e 76 61 6c 69 64 20 6f 70 74 69 6f 6e 0a 55 73 61 67 65 3a 09 62 61 73 68 20 5b 47 4e 55 20 6c 6f 6e 67 20 6f 70 74 ... 384 more bytes>
}

And separately, 👍 @ Node 16

@dcroote
Copy link
Contributor Author

dcroote commented Oct 17, 2022

A [Uint8Array] output will be unreadable though?

Yes good point. Erroring is only partially what we want; this message isn't helpful.

AFAIK is because a throw occurs before the printing to the terminal of the output of stdout and stderr - so you could move the throw a few lines and then you will get the stderr/stdout output?

I looked and your comment in 1493 refers to runCommand in the airnode-examples package. The docker builds use a different, more limited implementation without printing and with execSync rather than spawnSync:

export const runCommand = (command: string, options?: ExecSyncOptions) => {
logger.log(`Running command: '${command}'${options ? ` with options ${JSON.stringify(options)}` : ''}`);
return execSync(command, options);
};

I'll have a look at taking what we need from the airnode-examples implementation.

@dcroote dcroote changed the title Throw on docker build error Catch and print docker build errors Oct 18, 2022
@dcroote
Copy link
Contributor Author

dcroote commented Oct 18, 2022

Updated! Now no need for NODE_OPTIONS. In the case of an error, the output is now (stdout and stderr are empty in this trivial example):

Running command: 'exit 1; docker build --no-cache --build-arg npmRegistryUrl=http://172.17.0.7:4873 --build-arg npmTag=local --tag api3/airnode-admin-dev:local --file packages/airnode-admin/docker/Dockerfile packa
ges/airnode-admin/docker'
(node:1082) UnhandledPromiseRejectionWarning: Error:
Command failed with non-zero status code: 1
Stderr: .
Stdout: .
    at runCommand (/build/docker/scripts/utils.ts:12:11)
    at buildContainers (/build/docker/scripts/prepare-containers.ts:57:13)
    at /build/docker/scripts/prepare-containers.ts:71:3
    at Generator.next (<anonymous>)
    at fulfilled (/build/docker/scripts/prepare-containers.ts:11:58)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

@aquarat aquarat self-requested a review October 18, 2022 07:49
Copy link
Contributor

@aquarat aquarat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated! Now no need for NODE_OPTIONS. In the case of an error, the output is now (stdout and stderr are empty in this trivial example):

Looks good :), thanks for fixing.

@dcroote dcroote merged commit d23503a into master Oct 19, 2022
@dcroote dcroote deleted the dcroote/issue1493 branch October 19, 2022 02:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Stream the output of docker build commands in packaging
3 participants