At Objective-C, I call the NSSetUncaughtExceptionHandler(&exceptionHandler)
method to log exceptions. How does it called in Swift?
4 Answers
As of Swift 2 (Xcode 7), you can pass Swift functions/closures to parameters taking a C function pointer. From the Xcode 7 release notes:
Native support for C function pointers: C functions that take function pointer arguments can be called using closures or global functions, with the restriction that the closure must not capture any of its local context.
So this compiles and works:
func exceptionHandler(exception : NSException) {
print(exception)
print(exception.callStackSymbols)
}
NSSetUncaughtExceptionHandler(exceptionHandler)
Or with an "inline" closure:
NSSetUncaughtExceptionHandler { exception in
print(exception)
print(exception.callStackSymbols)
}
This does exactly the same as the corresponding Objective-C code:
it catches otherwise uncaught NSException
s.
So this will be caught:
let array = NSArray()
let elem = array.objectAtIndex(99)
NOTE:- It does not catch any Swift 2 errors (from throw
) or Swift runtime errors, so this is not caught:
let arr = [1, 2, 3]
let elem = arr[4]
-
@DuraiAmuthan.H: How did you test that? – As I said in the answer, this works *only* with NSExceptions (from the Foundation framework). You *cannot* catch Swift runtime errors. – Martin R Feb 23 '16 at 15:03
-
3Oh ! I didn't notice that...so is there any way that we can catch swift runtime errors ? – Durai Amuthan.H Feb 24 '16 at 05:47
-
I get the compile error "C function pointer can only be formed from a reference to a 'func' or a literal closure" – MobileMon May 03 '16 at 13:25
-
1@MobileMon That probably means that your exceptionHandler is a method of some class, and not a global function. – Martin R May 03 '16 at 13:35
-
Any updates for Swift 3, or will this work equally as well? Thanks for sharing! Also any way to catch uncaught Swift errors like the one you mentioned? – Crashalot Oct 13 '16 at 01:35
-
@Crashalot: No changes for Swift 3. – Martin R Oct 13 '16 at 06:02
-
Thanks for the help! Do you know why Swift does not have a way to catch unexpected errors like Obj-C does? It would seem like a valuable thing to have. – Crashalot Oct 13 '16 at 23:34
-
@Crashalot: Compare http://stackoverflow.com/questions/38737880/uncaught-error-exception-handling-in-swift. – Martin R Oct 14 '16 at 02:48
-
1Awesome, thanks so much! And thanks for sharing your knowledge in such a kind, supportive manner. Many of your peers with high rep lack the same kindness you have. Thanks again! – Crashalot Oct 14 '16 at 04:57
-
2If you want more pretty-printed stack trace, use `exception.callStackSymbols.joinWithSeparator("\n")` – Pavel Alexeev Oct 17 '16 at 22:21
-
2Can someone please explain where to use this code? I put it in didFinishLaunchingWithOptions i appdelegate, but it does not work – toing_toing Mar 27 '17 at 07:14
-
@MartinR Fabulous!! Any chance that we can make it work with swift errors ? – Jack May 16 '18 at 06:09
-
@Jack: No, I don't think so. https://stackoverflow.com/q/38737880/1187415 (which you apparently found already) has links to the documentation, where the rationale behind that design decision is explained. – Martin R May 16 '18 at 07:03
-
@MartinR, actually func exceptionHandler(exception : NSException) gets not called in my case, Could u please help me out in this with Swift 4 because I want to store data on my backend table with the API call in exceptionHandler(), Kindly reply. – iAj Aug 03 '18 at 11:52
-
Does it overrides Fabric exception handler? – bashan Jun 24 '19 at 15:04
-
@bashan: Unfortunately I do not have experience with Fabric, therefore I cannot tell. – Martin R Jun 24 '19 at 15:22
-
@iAj could you please tell me that have you resolved your answer if so because in my case also exception gets not called and the same thingi want to send data on my backend table with api call. – Sai Kishore Jul 27 '20 at 13:05
-
1@SaiKishore not till date, I postpone this part right now – iAj Jul 28 '20 at 16:24
Update
With Swift 2, you can pass Swift functions and closures as C function pointer. See Martin R's answer below.
Original answer
You can't, as of Xcode 6 beta 6.
Swift does support passing around function pointers, but they're treated pretty much like opaque pointers. You can't neither define a C function pointer to a Swift function nor can you call a C function pointer in Swift.
That means you call NSSetUncaughtExceptionHandler()
from Swift, but the handler must be implemented in Objective-C. You need a header file like this:
volatile void exceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *exceptionHandlerPtr;
and in the implementation, you need something like this:
volatile void exceptionHandler(NSException *exception) {
// Do stuff
}
NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHandler;
After you imported the header file in the Swift bridging header, you can set up the exception handler as usual:
NSSetUncaughtExceptionHandler(exceptionHandlerPtr)
-
-
@jou I am following your method. I pasted | volatile void exceptionHandler(NSException *exception); extern NSUncaughtExceptionHandler *exceptionHandlerPtr; | in my Bridging-Header.h file and add this | volatile void exceptionHandler(NSException *exception) { // Do stuff } NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHander; | in my Bridging-Header.m file and calling from swift appDelegat's Method | didFinishLaunchingWithOptions | like this NSSetUncaughtExceptionHandler(exceptionHandlerPtr) but ... continues to next comment – Qadir Hussain Mar 05 '15 at 09:04
-
But I am getting error Undefined symbols for architecture i386: "_exceptionHandlerPtr", referenced from: __TFC25Home_Automation_Sys_Swift11AppDelegate11applicationfS0_FTCSo13UIApplication29didFinishLaunchingWithOptionsGSqGVSs10DictionaryCSo8NSObjectPSs9AnyObject____Sb in AppDelegate.o ld: symbol(s) not found for architecture i386 – Qadir Hussain Mar 05 '15 at 09:06
-
@billy can you help me on this? how you have implemented this. please look my above comments – Qadir Hussain Mar 05 '15 at 10:02
-
@QadirHussain You need to implement the exception handler in a separate `.h`/`.m` pair and then import the header into the bridging header. – jou Mar 05 '15 at 12:56
-
Swift 5:
1. Add this method to AppDelegate:
func storeStackTrace() {
NSSetUncaughtExceptionHandler { exception in
print(exception)
// do stuff with the exception
}
}
2. Call this method from didFinishLaunchingWithOptions and raise the exception immediately after
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
storeStackTrace()
let exception = NSException(name: NSExceptionName(rawValue: "arbitrary"), reason: "arbitrary reason", userInfo: nil)
exception.raise()
}
3. Follow up on the console output, it will immediately print out the exception you just raised starting with the reason you provided.

- 171
- 1
- 6
-
It's crashing for me. *** Terminating app due to uncaught exception 'arbitrary', reason: 'arbitrary reason' *** First throw call stack: – Dhyaan Apr 13 '20 at 18:42
-
2Hi @Dhyaan, well it should crash, this is expected :) You are deliberately causing the crash by: exception.raise(). Intention is to track the exception in the storeStackTrace() method above – Milos Dimic Apr 13 '20 at 19:28
The error you can see at the reopen of a subsequent application in this way.
This code for swift 4.
Add in didFinishLaunchingWithOptions()
:
NSSetUncaughtExceptionHandler { exception in
print("Error Handling: ", exception)
print("Error Handling callStackSymbols: ", exception.callStackSymbols)
UserDefaults.standard.set(exception.callStackSymbols, forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
}
And The code add in fistViewController viewLoad()
// ERROR ExceptionHandler
if let exception = UserDefaults.standard.object(forKey: "ExceptionHandler") as? [String] {
print("Error was occured on previous session! \n", exception, "\n\n-------------------------")
var exceptions = ""
for e in exception {
exceptions = exceptions + e + "\n"
}
AlertFunctions.messageType.showYesNoAlert("Error was occured on previous session!", bodyMessage: exceptions, {
}, no: {
UserDefaults.standard.removeObject(forKey: "ExceptionHandler")
UserDefaults.standard.synchronize()
})
}
EDIT: The code work. But you need reopen your application after error.

- 569
- 7
- 13
-
1I have added code in swift but exception handler not working. Could you please advice me why? – Anjan Jan 18 '18 at 14:31
-
Crash Reporter for iPhone Applications [Part1](https://creativeinaustria.wordpress.com/2008/10/18/crash-reporter-for-iphone-applications/) and [Part2](https://creativeinaustria.wordpress.com/2008/10/20/crash-reporter-for-iphone-applications-part-2/) – Yunus T. Jan 19 '18 at 20:07
-
Dear Yunus I'm trying the same thing but I get this error: "A C function pointer cannot be formed from a closure that captures context", is there anything I'm missing? – Niloufar Jan 19 '19 at 11:35
-
-
Can you please help me understand how do I use it to track crashes like 'Index Out Of bounds'? – Karan Bhatia Jun 16 '21 at 05:40