How to trap set -o nounset in bash

I have a bash script using "set -o nounset" to prevent unset variables.

However I have created a trap to run some cleanup options upon exit of the script which works fine for CTRL-C, etc. but if it hits and unset variable the trap does not run and the script bails out without having tidied up after itself.

I have been trying various signals but none seem to cause the trap to execute when hitting and unset variable.

What signal does "set -o nounset" use?

Below is an example (I have tried various other signals)

#!/bin/bash

set -u

trap "echo trap_has_run > /tmp/foo.txt" 1 2 3 15 ERR

echo $unsetvar
> /tmp/traptest.sh
/tmp/traptest.sh: line 7: unsetvar: unbound variable
> cat  /tmp/foo.txt
cat: /tmp/foo.txt: No such file or directory

It is just a bit in VM, where is the signal?

Why not avoid touching unset variables in the trap or whatever ?

$ truss bash -c 'set -u ; echo mark ; echo $haha'
execve("/ndmtest/clmstux/nbkodln/myroot/usr/local/bin/bash", 0x7b0f54b8, 0x7b0f54c8) = 0 [32-bit]
 .
 .
 .
sigsetstatemask(0x17, NULL, 1073851480)                    = 0
getpeername(0, 0x7b0f59a0, 0x7b0f599c)                     ERR#216 ENOTSOCK
sigsetstatemask(0x17, NULL, 1073851480)                    = 0
sigsetstatemask(0x17, NULL, 1073851480)                    = 0
mark
write(1, "m a r k \n", 5)                                  = 5
bash: haha: unbound variable
write(2, "b a s h :   h a h a :   u n b o ".., 29)         = 29
sigsetstatemask(0x17, 0x4001ac58, 0)                       = 0
sigsetstatemask(0x17, 0x4001ac58, 0)                       = 0
exit(127) 

So that means it will run the trap on normal exit of the script, assuming EXIT is used... Looks like I will have to rethink how my cleanup operates as I had planned on only running the trap on script failure and had hoped it would capture "set -u" exit's.

Could you elaborate on you second sentence?

It is possible to test before you touch. Personally, I turn it off and write scripts where unset and "" are equivalent. It makes for more code and more ways to fail, more costly than can be offset by any speed it adds to debugging!