Throw is deactivated during kernel initialization. The following function can determine if
Throw is inoperative:
throwInoperativeQ := CheckAll[Catch[Throw[False]], # /. Null -> True &]
The undocumented function CheckAll is used here because
Check also appears to be unreliable when
Throw is inoperative.
If we make the assumption that
Throw is non-functional if and only if the kernel is still initializing, then we can define:
kernelInitializingQ = throwInoperativeQ;
The deactivation of
Throw during initialization seems to be intentional but it might be changed in some future release. This behaviour goes back to at least V7 and probably even earlier. It was reported to WRI and given the classification number [TS 86]. It is the root cause of the defect described in (17164).
I feel that this work-around is on very shaky ground given that it uses an undocumented function, undocumented behaviour, and a lot of guesswork. I offer it up "for science".
Work-around for complex initializations
There are many cases where code that does more than install definitions will fail at start-up. This may very well be due to the deactivation of
Throw and similar non-local control flow constructs. If this behaviour is changed is some future release, it may reduce or eliminate the need to detect whether initialization is in progress. In the meantime, using an immediately scheduled task might dodge the problem (depending upon the exact nature of the initialization):
(* perform some complex initialization *)
; RemoveScheduledTask @ $ScheduledTask