The error is happening when result.normal is (0,1,0), or extremely close to it.
look_at() defaults to assuming the up direction of the node is (0,1,0). Usually this is fine, when you look in most directions you don't want the node rolling to the side or upside down. But when you want to look directly up, look_at() doesn't know exactly what you want, there's an infinite number of ways to look straight up. So in that situation you need to give it an alternative up vector.
(The same thing would happen with trying to look straight down)
So the way to solve it would be to check if result.normal is very close to vertical (up or down) and if so then provide an up vector to look_at().
Something like (untested):
if (abs(n.y)>0.99):
impact.look_at(p+n, Vector3(0,0,1))
else:
impact.look_at(p+n)
This is the equivalent of telling a person that when they look directly up, the top of their head should point south.
The abs() part is to check both looking straight up and down in one go.
I don't know if 0.99 is too or not enough lenient, I don't know what is_equal_approx's precision is. Should be ok. Better to trigger it more often than needed (might visually be off a fraction of a degree) than not enough (error happens).