The goal of mutation testing is to verify that a test suite can detect the kind of errors that the mutation testing system introduces in the code under test. This means that the mutation testing system exercises two pieces of software: the code under test that is subject to mutations and a suite of tests that tries to establish whether the code under test functions correctly.
A good testing framework marks a testcase as failed when an unexpected exception occurs (while a bad framework would just abort the run due to an unhandled exception). This means that if the mutant throws an exception, this should result in a different test result and the exception should not be visible to the mutation testing system.
The non-termination of a testcase is typically not caught by the testing framework, although some may catch it based on mocked functions being called too often.
For the mutation testing system, I would treat non-termination of a test run as a fault that does get detected by the combination of testsuite and human operator.
In my view, if an exception makes it to the mutation testing system, then that should be flagged as a problem in the testsuite, not the code under test.
In both cases, the mutant can be considered as killed.