I was also trying to figure out a similar issue I was having with twin-stick aiming controls, and the code in your question helped me make a breakthrough. These are the changes I made that got it to work:
var deadzone = 0.5
var controllerangle = Vector2.ZERO
var xAxisRL = Input.get_joy_axis(0, JOY_AXIS_2)
var yAxisUD = Input.get_joy_axis(0 ,JOY_AXIS_3)
if abs(xAxisRL) > deadzone || abs(yAxisUD) > deadzone:
controllerangle = Vector2(xAxisRL, yAxisUD).angle()
$Gun.rotation = controllerangle
abs()function was removing sign info (positive/negative) needed to correctly set the directions in the
controllerangle's Vector2, and the
rotate()function you were using "Applies a rotation to the node, in radians, starting from its current rotation", so was rotating to a relative direction rather than the absolute one you wanted.
I know it's way late, but I hope this helps.