0
# Stage to pull and push image
job1:
  stage: job1


  allow_failure: true

  script:

    # Pull image and save success
    - docker pull ${SOURCE_IMAGEURI}:${TAG}

    ...

    - docker tag ${SOURCE_IMAGEURI}:${TAG} ${TARGET_IMAGEURI}:${TAG} 
    
    # Job might fail here due to not enough permissions which is what I want to happen
    - docker push ${TARGET_IMAGEURI}:${TAG} 

    - echo "Error Message" > curldata.txt
  artifacts:
    when: always
    paths:
      - curldata.txt
job2:
  stage: job2
  script:

    # Do something with the error that happened in job1

  when: always
  dependencies:
    - job1

So above is a part of a job that pulls and pushes an image. Sometimes the image will fail to push though as a safety step due to lack of permissions. How would I capture the error that happens so that I can send that artifacts to the next feedback job. This job will send the information to the user so he/she knows that they didnt have enough permissions.

John Baltimore
  • 77
  • 2
  • 10
  • If you capture the error as an environment variable you should be able to pass that to another job as a dotenv artifact: https://docs.gitlab.com/ee/ci/variables/#pass-an-environment-variable-to-another-job – Geoffrey Nov 18 '21 at 18:16
  • I see what you mean, but I am not sure what env var to capture and also it needs to be captured after the job fails which I am confused about because even if you allow failure, the job that fails will stop immediately and not capture the env var. Do you have any info on that? – John Baltimore Nov 18 '21 at 19:22

1 Answers1

2

You can tee the (stderr) output of the command to a file and artifact the file.

script:
  # ...
  # show output of the command and store stderr to text file
  - docker push ${TARGET_IMAGEURI}:${TAG} 2> >(tee stderr.txt)
artifacts:
  paths:
    - stderr.txt
  when: always

If you need some logic to happen after the error, you can use and/or logic gates.

docker push ${TARGET_IMAGEURI}:${TAG} || echo "do this if it fails" > error.txt && exit 1

There's more to be said about robust error handling in bash, but those are some basic ideas you can use.

sytech
  • 29,298
  • 3
  • 45
  • 86
  • Thank you, although I am not quite sure what the "2> >" part does, it solves my problem and I was able to capture that error message! Also, I have not used tee before so I am not sure the differences between that and a normal output without that. – John Baltimore Nov 18 '21 at 20:37
  • The `2>` is a kind of output redirection. It says, basically, "send stderr somewhere" `>(tee stderr.txt)` directs stderr into the [`tee` command](https://man7.org/linux/man-pages/man1/tee.1.html), which will read the input, and then write it to both the file `stderr.txt` AND to the screen (stdout). These may help: [bash: redirect stderr to file and stdout + stderr to screen](https://unix.stackexchange.com/q/333198/453397) and [In the shell, what does " 2>&1 " mean?](https://stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean) @JohnBaltimore – sytech Nov 18 '21 at 21:32
  • Thanks a bunch! One last question. So if I wanted logic if it fails, how would I get the stderr.txt with the error in it? "|| 2> >(tee stderr.txt) && do something" will have nothing in the txt file – John Baltimore Nov 18 '21 at 21:41
  • The error is already written to the file before the the OR logic (`||`) kicks in. You need to have the `2> >(tee stderr.txt)` BEFORE the `||`. Also keep in mind if you do another redirection into the file again (like `echo "foo" > stderr.txt` ) it will truncate (delete) the contents of the file from the first command. Use `>>` to append. @JohnBaltimore Hope that helps. If you need more help with bash logic, consider opening a new question – sytech Nov 18 '21 at 23:05