I actually found this question because I have a similar issue, hope my answer is still helpful.
If I understand you correctly, the rectangular walls you build during play are made up from individual square collision boxes? Then the odd bounces probably come from the ball hitting the corners of a square.
I used the following code to make sure the collision happens along the cardinal axes (keep in mind I'm on Godot 4):
var n = collision.get_normal()
# For the collision, it doesn't matter if the collision box goes from left to right or right to left
var nx = abs(n.x)
var ny = abs(n.y)
if nx > ny:
n = Vector2.RIGHT if n.x > 0 else Vector2.LEFT
else:
n = Vector2.UP if n.y > 0 else Vector2.DOWN
velocity = velocity.bounce(n)
The whole if-part can probably shortened to n = Vector2.RIGHT if nx > ny else Vector2.UP
, but not sure if that would have undesired side effects.
I feel like there should be a cleaner solution, especially since this becomes a bit messy if I want to handle more complex collision behavior or different kinds of collision boxes, but it should work for your situation.
Also, if you don't already, make sure to put all collision-related code in _physics_process and not in _process