How to signal errors / failures in App Intents?

Hello,

the new AppIntents allow a simple code-driven implementation for Siri Shortcuts. In the perform() function we need to return some IntentResult or throw an error if something went wrong.

My question now is: How do I throw an error that can then be inspected by the user? Let's say the user wants to interact with a CoreData object that he has deleted earlier. Now he/she runs the shortcut and it must fail, because the object is not available. I tried to implement a custom LocalizedError, but in the Shortcuts app I only get an error message telling me something about an unknown error. The description text is not shown in Shortcuts.

Feedback ID: FB11434135

Kind regards
Alex

Accepted Reply

I couldn't find any documentation on this, but during the migration of my intents I ended up using a property localizedStringResource like this:

struct MyIntent: AppIntent {
	static let title: LocalizedStringResource = "Start My Intent"

	func perform() async throws -> some IntentResult {

		if !doSomething() {
			throw MyIntentError.message("Hello, I'm an error!")
		}
		
		return .result(dialog: IntentDialog("My answer"))
	}
	
	func doSomething() -> Bool {
		return false
	}
}

enum MyIntentError: Swift.Error, CustomLocalizedStringResourceConvertible {
	case general
	case message(_ message: String)

	var localizedStringResource: LocalizedStringResource {
		switch self {
		case let .message(message): return "Error: \(message)"
		case .general: return "My general error"
		}
	}
}
  • I got a reply from Apple on the feedback. Apparently the CustomLocalizedStringResourceConvertible is the right way to do it. It was documented on a WWDC video, but it’s not mentioned in the SDK documentation

  • Great. I looked it up. It's at 15m:35s in session WWDC 2022 10032 that can be found here https://developer.apple.com/videos/play/wwdc2022/10032/

Add a Comment

Replies

I couldn't find any documentation on this, but during the migration of my intents I ended up using a property localizedStringResource like this:

struct MyIntent: AppIntent {
	static let title: LocalizedStringResource = "Start My Intent"

	func perform() async throws -> some IntentResult {

		if !doSomething() {
			throw MyIntentError.message("Hello, I'm an error!")
		}
		
		return .result(dialog: IntentDialog("My answer"))
	}
	
	func doSomething() -> Bool {
		return false
	}
}

enum MyIntentError: Swift.Error, CustomLocalizedStringResourceConvertible {
	case general
	case message(_ message: String)

	var localizedStringResource: LocalizedStringResource {
		switch self {
		case let .message(message): return "Error: \(message)"
		case .general: return "My general error"
		}
	}
}
  • I got a reply from Apple on the feedback. Apparently the CustomLocalizedStringResourceConvertible is the right way to do it. It was documented on a WWDC video, but it’s not mentioned in the SDK documentation

  • Great. I looked it up. It's at 15m:35s in session WWDC 2022 10032 that can be found here https://developer.apple.com/videos/play/wwdc2022/10032/

Add a Comment