I'd pretty much always store pitch/yaw for a first/third person controller. This makes it trivial to modify the values in response to input - `pitch += mouse_delta.y` and to clamp the pitch to a sane range (-90 to 90 deg) afterwards.
You can then calculate a quaternion from the pitch/yaw and do whatever additional transforms you wish (e.g. temporary rotation for recoil, or roll when peeking around a corner).
Quaternions break down for other situations. They cannot represent a rotation greater than 360 degrees. In an engine like Unity (which stores rotation as quats), you can use arbitrary Euler angles in the editor and it will work fine, but the scene file has to store 2 things. There is an additional m_LocalEulerAnglesHint property that covers this edge case.