Recently, when I looked at the CI run of a project, I occasionally found one or two images that were built successfully but the container didn’t run. The reason is an exit code problem

Shanyue. tech/post/exit-c…

throw new ErrorPromise.rejectThe difference between

The first code throws an exception and the second code promises. Reject. Both codes print an exception.

function error () {
  throw new Error('hello, error')
}

error()
// /Users/shanyue/Documents/note/demo.js:2
// throw new Error('hello, world')
/ / ^
// 
// Error: hello, world
// at error (/Users/shanyue/Documents/note/demo.js:2:9)
// at Object.
      
        (/Users/shanyue/Documents/note/demo.js:5:1)
      
// at Module._compile (internal/modules/cjs/loader.js:701:30)
Copy the code
async function error () {
  return new Error('hello, error')
}

error()

// (node:60356) UnhandledPromiseRejectionWarning: Error: hello, world
// at error (/Users/shanyue/Documents/note/demo.js:2:9)
// at Object.
      
        (/Users/shanyue/Documents/note/demo.js:5:1)
      
// at Module._compile (internal/modules/cjs/loader.js:701:30)
// at Object.Module._extensions.. js (internal/modules/cjs/loader.js:712:10)
Copy the code

At a lower level, the exit code is different, so what is an exit code?

exit code

exit codeThe return code representing a process, via a system callexit_groupTo trigger. inPOSIX,0Represents the normal return code, and1-255.Represents an exception return code, but usually an error code1. Here is a attached tableAppendix E. Exit Codes With Special Meanings

As a result, process.exit(1) is often used in Node applications to represent an interruption due to an unexpected exception.

Now look at an exception about cat and its exit code and system call

$ cat a
cat: a: No such file or directory

# -eIndicates that only write and exit_group system calls are displayed
$ strace -e write,exit_group cat a
write(2, "cat: ", 5cat: )                    = 5
write(2, "a", 1a)                        = 1
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
)                       = 1
exit_group(1)                           = ?
+++ exited with 1 +++
Copy the code

As you can see, its exit code is 1 and it writes the error message to stderr (fd of standard error is 2)

How do I view exit Code

You can use strace to determine the exit code of a process. But this is just too inconvenient, especially in a shell programming environment.

There is an easy way throughecho $?To output the return code

$ cat a
cat: a: No such file or directory

$ echo $?
1
Copy the code

Dockerfile in node

Now that we’re done with node exceptions and exit code, it’s time to talk about associations with dockerfiles.

When building an image using Dockerfile, the build will fail if the RUN process returns a non-zero return code.

In Node error handling, we tend to leave all exceptions to async/await, and when an exception occurs, exit code 0 will not cause the image build to fail. As shown below.

FROM node:alpine

RUN node -e "Promise.reject('hello, world')"
Copy the code
$ docker build -t demo .Sending build context to Docker Daemon 14.85KB Step 1/2: FROM node:alpine ---> d97a436daee9
Step 2/2 : RUN node -e "Promise.reject('hello, world')"
 ---> Running in 0281c660ab82(node:1) UnhandledPromiseRejectionWarning: hello, world (node:1) 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 handled with .catch(). (rejection id: 1) (node:1) [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. Removing intermediate container 0281c660ab82 ---> 2146545654d2
Successfully built 2146545654d2
Successfully tagged demo:latest
Copy the code

Problems that can be found at compile time should never be exposed at run time. Therefore, if you need to execute node scripts to build the image, you need to manually specify 1 for exception handlingexit code:process.exit(1).

runScript().catch((a)= > {
  process.exit(1)})Copy the code

Welcome to pay attention to my public number shanyuexixing, here records my technical growth, welcome to exchange