Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Add `attachAllThreads` and scope block overloads for `capture(event:)`, `capture(error:)`, `capture(exception:)`, and `capture(message:)`, also available through `SentryObjC` (#9424)

## 9.31.0

### Features
Expand Down
49 changes: 49 additions & 0 deletions Sources/SentryObjC/Public/SentryObjCSDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (SentryObjCId *)captureEvent:(SentryObjCEvent *)event attachAllThreads:(BOOL)attachAllThreads;

/**
* Captures a manually created event and sends it to Sentry, with a per-call override for
* attaching all threads with stack traces. Maintains the global scope but mutates scope data for
* only this call.
* @param event The event to send to Sentry.
* @param attachAllThreads Whether to attach all threads with full stack traces.
* @param block The block mutating the scope only for this call.
* @return The @c SentryObjCId of the event or an empty ID if the event is not sent.
*/
+ (SentryObjCId *)captureEvent:(SentryObjCEvent *)event
attachAllThreads:(BOOL)attachAllThreads
scopeBlock:(void (^)(SentryObjCScope *))block;

/**
* Captures a manually created event and sends it to Sentry with a user-provided hint.
* @param event The event to send to Sentry.
Expand Down Expand Up @@ -259,6 +272,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (SentryObjCId *)captureError:(NSError *)error attachAllThreads:(BOOL)attachAllThreads;

/**
* Captures an error event and sends it to Sentry, with a per-call override for attaching all
* threads with stack traces. Maintains the global scope but mutates scope data for only this call.
* @param error The error to send to Sentry.
* @param attachAllThreads Whether to attach all threads with full stack traces.
* @param block The block mutating the scope only for this call.
* @return The @c SentryObjCId of the event or an empty ID if the event is not sent.
*/
+ (SentryObjCId *)captureError:(NSError *)error
attachAllThreads:(BOOL)attachAllThreads
scopeBlock:(void (^)(SentryObjCScope *))block;

/**
* Captures an error event and sends it to Sentry with a user-provided hint.
* @param error The error to send to Sentry.
Expand Down Expand Up @@ -326,6 +351,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (SentryObjCId *)captureException:(NSException *)exception attachAllThreads:(BOOL)attachAllThreads;

/**
* Captures an exception event and sends it to Sentry, with a per-call override for attaching all
* threads with stack traces. Maintains the global scope but mutates scope data for only this call.
* @param exception The exception to send to Sentry.
* @param attachAllThreads Whether to attach all threads with full stack traces.
* @param block The block mutating the scope only for this call.
* @return The @c SentryObjCId of the event or an empty ID if the event is not sent.
*/
+ (SentryObjCId *)captureException:(NSException *)exception
attachAllThreads:(BOOL)attachAllThreads
scopeBlock:(void (^)(SentryObjCScope *))block;

/**
* Captures an exception event and sends it to Sentry with a user-provided hint.
* @param exception The exception to send to Sentry.
Expand Down Expand Up @@ -393,6 +430,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (SentryObjCId *)captureMessage:(NSString *)message attachAllThreads:(BOOL)attachAllThreads;

/**
* Captures a message event and sends it to Sentry, with a per-call override for attaching all
* threads with stack traces. Maintains the global scope but mutates scope data for only this call.
* @param message The message to send to Sentry.
* @param attachAllThreads Whether to attach all threads with full stack traces.
* @param block The block mutating the scope only for this call.
* @return The @c SentryObjCId of the event or an empty ID if the event is not sent.
*/
+ (SentryObjCId *)captureMessage:(NSString *)message
attachAllThreads:(BOOL)attachAllThreads
scopeBlock:(void (^)(SentryObjCScope *))block;

/**
* Captures a message event and sends it to Sentry with a user-provided hint.
* @param message The message to send to Sentry.
Expand Down
56 changes: 32 additions & 24 deletions Sources/SentryObjCCompat/SentryObjCSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,19 @@ import Foundation

@objc(captureEvent:withScopeBlock:)
@discardableResult public static func capture(event: SentryObjCEvent, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(event: event.wrapped) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(event: event.wrapped, block: bridged(block)))
}

@objc(captureEvent:attachAllThreads:)
@discardableResult public static func capture(event: SentryObjCEvent, attachAllThreads: Bool) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(event: event.wrapped, attachAllThreads: attachAllThreads))
}

@objc(captureEvent:attachAllThreads:scopeBlock:)
@discardableResult public static func capture(event: SentryObjCEvent, attachAllThreads: Bool, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(event: event.wrapped, attachAllThreads: attachAllThreads, block: bridged(block)))
}

@objc(captureEvent:withHint:)
@discardableResult public static func capture(event: SentryObjCEvent, hint: SentryObjCHint) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(event: event.wrapped, hint: hint.wrapped))
Expand All @@ -87,9 +90,7 @@ import Foundation

@objc(captureEvent:withHint:scopeBlock:)
@discardableResult public static func capture(event: SentryObjCEvent, hint: SentryObjCHint, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(event: event.wrapped, hint: hint.wrapped) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(event: event.wrapped, hint: hint.wrapped, block: bridged(block)))
}

@objc @discardableResult public static func startTransaction(name: String, operation: String) -> SentryObjCSpan {
Expand Down Expand Up @@ -132,16 +133,19 @@ import Foundation

@objc(captureError:withScopeBlock:)
@discardableResult public static func capture(error: Error, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(error: error) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(error: error, block: bridged(block)))
}

@objc(captureError:attachAllThreads:)
@discardableResult public static func capture(error: Error, attachAllThreads: Bool) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(error: error, attachAllThreads: attachAllThreads))
}

@objc(captureError:attachAllThreads:scopeBlock:)
@discardableResult public static func capture(error: Error, attachAllThreads: Bool, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(error: error, attachAllThreads: attachAllThreads, block: bridged(block)))
}

@objc(captureError:withHint:)
@discardableResult public static func capture(error: Error, hint: SentryObjCHint) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(error: error, hint: hint.wrapped))
Expand All @@ -154,9 +158,7 @@ import Foundation

@objc(captureError:withHint:scopeBlock:)
@discardableResult public static func capture(error: Error, hint: SentryObjCHint, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(error: error, hint: hint.wrapped) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(error: error, hint: hint.wrapped, block: bridged(block)))
}

@objc(captureException:)
Expand All @@ -171,16 +173,19 @@ import Foundation

@objc(captureException:withScopeBlock:)
@discardableResult public static func capture(exception: NSException, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(exception: exception) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(exception: exception, block: bridged(block)))
}

@objc(captureException:attachAllThreads:)
@discardableResult public static func capture(exception: NSException, attachAllThreads: Bool) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(exception: exception, attachAllThreads: attachAllThreads))
}

@objc(captureException:attachAllThreads:scopeBlock:)
@discardableResult public static func capture(exception: NSException, attachAllThreads: Bool, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(exception: exception, attachAllThreads: attachAllThreads, block: bridged(block)))
}

@objc(captureException:withHint:)
@discardableResult public static func capture(exception: NSException, hint: SentryObjCHint) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(exception: exception, hint: hint.wrapped))
Expand All @@ -193,9 +198,7 @@ import Foundation

@objc(captureException:withHint:scopeBlock:)
@discardableResult public static func capture(exception: NSException, hint: SentryObjCHint, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(exception: exception, hint: hint.wrapped) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(exception: exception, hint: hint.wrapped, block: bridged(block)))
}

@objc(captureMessage:)
Expand All @@ -210,16 +213,19 @@ import Foundation

@objc(captureMessage:withScopeBlock:)
@discardableResult public static func capture(message: String, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(message: message) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(message: message, block: bridged(block)))
}

@objc(captureMessage:attachAllThreads:)
@discardableResult public static func capture(message: String, attachAllThreads: Bool) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(message: message, attachAllThreads: attachAllThreads))
}

@objc(captureMessage:attachAllThreads:scopeBlock:)
@discardableResult public static func capture(message: String, attachAllThreads: Bool, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(message: message, attachAllThreads: attachAllThreads, block: bridged(block)))
}

@objc(captureMessage:withHint:)
@discardableResult public static func capture(message: String, hint: SentryObjCHint) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(message: message, hint: hint.wrapped))
Expand All @@ -232,9 +238,7 @@ import Foundation

@objc(captureMessage:withHint:scopeBlock:)
@discardableResult public static func capture(message: String, hint: SentryObjCHint, block: @escaping (SentryObjCScope) -> Void) -> SentryObjCId {
SentryObjCId(SentrySDK.capture(message: message, hint: hint.wrapped) { scope in
block(SentryObjCScope(scope))
})
SentryObjCId(SentrySDK.capture(message: message, hint: hint.wrapped, block: bridged(block)))
}

@objc(captureFeedbackWithMessage:name:email:source:associatedEventId:attachments:)
Expand Down Expand Up @@ -348,5 +352,9 @@ import Foundation
SentrySDK.stopProfiler()
}
#endif

private static func bridged(_ block: @escaping (SentryObjCScope) -> Void) -> (Scope) -> Void {
{ block(SentryObjCScope($0)) }
}
}
// swiftlint:enable file_length type_body_length missing_docs
82 changes: 70 additions & 12 deletions Sources/Swift/Helper/SentrySDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,22 @@ extension SentrySDK {
return SentrySDKInternal.capture(event: event)
}

/// Captures a manually created event and sends it to Sentry, with a per-call override for
/// attaching all threads with stack traces. Maintains the global scope but mutates scope data for
/// only this call.
/// - Parameters:
/// - event: The event to send to Sentry.
/// - attachAllThreads: Whether to attach all threads with full stack traces. Overrides `Options.attachAllThreads`.
/// - block: The block mutating the scope only for this call.
/// - Returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
#if !SDK_V10
@objc(captureEvent:attachAllThreads:scopeBlock:)
#endif
@discardableResult public static func capture(event: Event, attachAllThreads: Bool, block: @escaping (Scope) -> Void) -> SentryId {
event.attachAllThreadsOverride = NSNumber(value: attachAllThreads)
return SentrySDKInternal.capture(event: event, block: block)
}

/// Captures a manually created event and sends it to Sentry with a user-provided hint.
/// The hint is passed to `beforeSend` callbacks, allowing inspection and modification.
/// - parameter event: The event to send to Sentry.
Expand All @@ -206,9 +222,7 @@ extension SentrySDK {
/// - parameter block: The block mutating the scope only for this call.
/// - returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
@discardableResult public static func capture(event: Event, hint: Hint, block: @escaping (Scope) -> Void) -> SentryId {
let scope = Scope(scope: SentrySDKInternal.currentHub().scope)
block(scope)
return SentrySDKInternal.capture(event: event, scope: scope, hint: hint)
return SentrySDKInternal.capture(event: event, scope: callScope(block), hint: hint)
}

// MARK: - Transaction Management
Expand Down Expand Up @@ -330,6 +344,20 @@ extension SentrySDK {
return hub.captureError(error as NSError, with: hub.scope, attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures an error event and sends it to Sentry, with a per-call override for attaching all
/// threads with stack traces. Maintains the global scope but mutates scope data for only this call.
/// - Parameters:
/// - error: The error to send to Sentry.
/// - attachAllThreads: Whether to attach all threads with full stack traces. Overrides `Options.attachAllThreads`.
/// - block: The block mutating the scope only for this call.
/// - Returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
#if !SDK_V10
@objc(captureError:attachAllThreads:scopeBlock:)
#endif
@discardableResult public static func capture(error: Error, attachAllThreads: Bool, block: @escaping (Scope) -> Void) -> SentryId {
return SentrySDKInternal.currentHub().captureError(error as NSError, with: callScope(block), attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures an error event and sends it to Sentry with a user-provided hint.
/// The hint is passed to `beforeSend` callbacks, allowing inspection and modification.
/// - parameter error: The error to send to Sentry.
Expand All @@ -356,9 +384,7 @@ extension SentrySDK {
/// - parameter block: The block mutating the scope only for this call.
/// - returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
@discardableResult public static func capture(error: Error, hint: Hint, block: @escaping (Scope) -> Void) -> SentryId {
let scope = Scope(scope: SentrySDKInternal.currentHub().scope)
block(scope)
return SentrySDKInternal.capture(error: error as NSError, scope: scope, hint: hint)
return SentrySDKInternal.capture(error: error as NSError, scope: callScope(block), hint: hint)
}

// MARK: - Exception Capture
Expand Down Expand Up @@ -411,6 +437,20 @@ extension SentrySDK {
return hub.capture(exception, with: hub.scope, attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures an exception event and sends it to Sentry, with a per-call override for attaching all
/// threads with stack traces. Maintains the global scope but mutates scope data for only this call.
/// - Parameters:
/// - exception: The exception to send to Sentry.
/// - attachAllThreads: Whether to attach all threads with full stack traces. Overrides `Options.attachAllThreads`.
/// - block: The block mutating the scope only for this call.
/// - Returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
#if !SDK_V10
@objc(captureException:attachAllThreads:scopeBlock:)
#endif
@discardableResult public static func capture(exception: NSException, attachAllThreads: Bool, block: @escaping (Scope) -> Void) -> SentryId {
return SentrySDKInternal.currentHub().capture(exception, with: callScope(block), attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures an exception event and sends it to Sentry with a user-provided hint.
/// The hint is passed to `beforeSend` callbacks, allowing inspection and modification.
/// - parameter exception: The exception to send to Sentry.
Expand All @@ -437,9 +477,7 @@ extension SentrySDK {
/// - parameter block: The block mutating the scope only for this call.
/// - returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
@discardableResult public static func capture(exception: NSException, hint: Hint, block: @escaping (Scope) -> Void) -> SentryId {
let scope = Scope(scope: SentrySDKInternal.currentHub().scope)
block(scope)
return SentrySDKInternal.capture(exception: exception, scope: scope, hint: hint)
return SentrySDKInternal.capture(exception: exception, scope: callScope(block), hint: hint)
}

// MARK: - Message Capture
Expand Down Expand Up @@ -492,6 +530,20 @@ extension SentrySDK {
return hub.captureMessage(message, with: hub.scope, attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures a message event and sends it to Sentry, with a per-call override for attaching all
/// threads with stack traces. Maintains the global scope but mutates scope data for only this call.
/// - Parameters:
/// - message: The message to send to Sentry.
/// - attachAllThreads: Whether to attach all threads with full stack traces. Overrides `Options.attachAllThreads`.
/// - block: The block mutating the scope only for this call.
/// - Returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
#if !SDK_V10
@objc(captureMessage:attachAllThreads:scopeBlock:)
#endif
@discardableResult public static func capture(message: String, attachAllThreads: Bool, block: @escaping (Scope) -> Void) -> SentryId {
return SentrySDKInternal.currentHub().captureMessage(message, with: callScope(block), attachAllThreads: NSNumber(value: attachAllThreads))
}

/// Captures a message event and sends it to Sentry with a user-provided hint.
/// The hint is passed to `beforeSend` callbacks, allowing inspection and modification.
/// - parameter message: The message to send to Sentry.
Expand All @@ -518,9 +570,7 @@ extension SentrySDK {
/// - parameter block: The block mutating the scope only for this call.
/// - returns: The `SentryId` of the event or `SentryId.empty` if the event is not sent.
@discardableResult public static func capture(message: String, hint: Hint, block: @escaping (Scope) -> Void) -> SentryId {
let scope = Scope(scope: SentrySDKInternal.currentHub().scope)
block(scope)
return SentrySDKInternal.capture(message: message, scope: scope, hint: hint)
return SentrySDKInternal.capture(message: message, scope: callScope(block), hint: hint)
}

/// Captures user feedback that was manually gathered and sends it to Sentry.
Expand Down Expand Up @@ -883,6 +933,14 @@ extension SentrySDK {
@_spi(Private) public static func setStart(with option: Options?) {
SentryDependencyContainer.sharedInstance().startOptions = option
}

/// Copies the current hub scope and applies `block` to the copy, so the mutations only
/// affect a single capture call.
private static func callScope(_ block: (Scope) -> Void) -> Scope {
let scope = Scope(scope: SentrySDKInternal.currentHub().scope)
block(scope)
return scope
}
}

// swiftlint:enable file_length
Loading
Loading