The arm architetural refernce documents are quite clear on how this works. You need to refer to the documents for the core you are using for specific details in case there are differences. The cortex-m vs non-cortex-m are definitely quite different. the non-cortex-m (cortex-a, arm11, etc) have pseudo code in the documentation for each handler and I believe that they switch to arm mode. The only processors with arm mode and thumb2 are the most recent cortex-a's. so if you are asking what is the difference between a cortex-m and non-cortex-m. again that is well documented in the arm docs, but:
the cortex-m is designed for not needing to have assembly language wrappers (or compiler specific directives that generate that additional assembly) in order to protect gprs and return with the right instruction. The cortex-m does that in hardware and is designed to be able to have the address of a C function right in the interrupt vector table. The non-cortex-ms generally dont support thumb2, but when in thumb mode or arm mode I believe they switch to arm mode for the handler which you can switch back of course. You have separate stacks on a non cortex-m and you have banked registers. so depending on the interrupt and your handler you may need to preserve more interrupts, and you certainly cannot simply return with bx lr you have to use the proper return instruction based on the exception.
also the cortex-m uses a list of addresses in the vector table, where a traditional arm uses a list of instructions (usually you need to use branch b or ldr pc to get out of the table in one instruction).