Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose ZoneSpecification parameters for package stack_trace #1949

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
75 changes: 63 additions & 12 deletions pkgs/stack_trace/lib/src/chain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,67 @@ class Chain implements StackTrace {
/// If [callback] returns a value, it will be returned by [capture] as well.
///
/// [zoneValues] is added to the [runZoned] calls.
static T capture<T>(T Function() callback,
{void Function(Object error, Chain)? onError,
bool when = true,
bool errorZone = true,
Map<Object?, Object?>? zoneValues}) {
///
/// Other values from [ZoneSpecification] are exposed in this constructor and
/// will be forwarded to the [Zone] created.
static T capture<T>(
T Function() callback, {
void Function(Object error, Chain)? onError,
bool when = true,
bool errorZone = true,
Map<Object?, Object?>? zoneValues,
RunHandler? run,
RunUnaryHandler? runUnary,
RunBinaryHandler? runBinary,
ScheduleMicrotaskHandler? scheduleMicrotask,
CreateTimerHandler? createTimer,
CreatePeriodicTimerHandler? createPeriodicTimer,
PrintHandler? print,
ForkHandler? fork,
}) {
if (!errorZone && onError != null) {
throw ArgumentError.value(
onError, 'onError', 'must be null if errorZone is false');
}

if (!when) {
if (onError == null) return runZoned(callback, zoneValues: zoneValues);
return runZonedGuarded(callback, (error, stackTrace) {
onError(error, Chain.forTrace(stackTrace));
}, zoneValues: zoneValues) as T;
final zoneSpec = ZoneSpecification(
run: run,
runUnary: runUnary,
runBinary: runBinary,
scheduleMicrotask: scheduleMicrotask,
createTimer: createTimer,
createPeriodicTimer: createPeriodicTimer,
print: print,
fork: fork,
);

if (onError == null) {
return runZoned(callback,
zoneValues: zoneValues, zoneSpecification: zoneSpec);
}
return runZonedGuarded(
callback,
(error, stackTrace) {
onError(error, Chain.forTrace(stackTrace));
},
zoneValues: zoneValues,
zoneSpecification: zoneSpec,
) as T;
}

var spec = StackZoneSpecification(onError, errorZone: errorZone);
var spec = StackZoneSpecification(
onError,
errorZone: errorZone,
run: run,
runUnary: runUnary,
runBinary: runBinary,
scheduleMicrotask: scheduleMicrotask,
createTimer: createTimer,
createPeriodicTimer: createPeriodicTimer,
print: print,
fork: fork,
);
return runZoned(() {
try {
return callback();
Expand All @@ -117,11 +160,19 @@ class Chain implements StackTrace {
/// [callback] in a [Zone] in which chain capturing is disabled.
///
/// If [callback] returns a value, it will be returned by [disable] as well.
static T disable<T>(T Function() callback, {bool when = true}) {
static T disable<T>(
T Function() callback, {
ZoneSpecification? zoneSpecification,
bool when = true,
}) {
var zoneValues =
when ? {_specKey: null, StackZoneSpecification.disableKey: true} : null;

return runZoned(callback, zoneValues: zoneValues);
return runZoned(
callback,
zoneValues: zoneValues,
zoneSpecification: zoneSpecification,
);
}

/// Returns [futureOrStream] unmodified.
Expand Down
57 changes: 50 additions & 7 deletions pkgs/stack_trace/lib/src/stack_zone_specification.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,59 @@ class StackZoneSpecification {
/// Whether this is an error zone.
final bool _errorZone;

StackZoneSpecification(this._onError, {bool errorZone = true})
: _errorZone = errorZone;
/// A custom [Zone.run] implementation for a new zone.
final RunHandler? run;

/// A custom [Zone.runUnary] implementation for a new zone.
final RunUnaryHandler? runUnary;

/// A custom [Zone.runBinary] implementation for a new zone.
final RunBinaryHandler? runBinary;

/// A custom [Zone.scheduleMicrotask] implementation for a new zone.
final ScheduleMicrotaskHandler? scheduleMicrotask;

/// A custom [Zone.createTimer] implementation for a new zone.
final CreateTimerHandler? createTimer;

/// A custom [Zone.createPeriodicTimer] implementation for a new zone.
final CreatePeriodicTimerHandler? createPeriodicTimer;

/// A custom [Zone.print] implementation for a new zone.
final PrintHandler? print;

/// A custom [Zone.handleUncaughtError] implementation for a new zone.
final ForkHandler? fork;

StackZoneSpecification(
this._onError, {
bool errorZone = true,
this.run,
this.runUnary,
this.runBinary,
this.scheduleMicrotask,
this.createTimer,
this.createPeriodicTimer,
this.print,
this.fork,
}) : _errorZone = errorZone;

/// Converts this specification to a real [ZoneSpecification].
ZoneSpecification toSpec() => ZoneSpecification(
handleUncaughtError: _errorZone ? _handleUncaughtError : null,
registerCallback: _registerCallback,
registerUnaryCallback: _registerUnaryCallback,
registerBinaryCallback: _registerBinaryCallback,
errorCallback: _errorCallback);
handleUncaughtError: _errorZone ? _handleUncaughtError : null,
registerCallback: _registerCallback,
registerUnaryCallback: _registerUnaryCallback,
registerBinaryCallback: _registerBinaryCallback,
errorCallback: _errorCallback,
run: run,
runBinary: runBinary,
runUnary: runUnary,
scheduleMicrotask: scheduleMicrotask,
createTimer: createTimer,
createPeriodicTimer: createPeriodicTimer,
print: print,
fork: fork,
);

/// Returns the current stack chain.
///
Expand Down
Loading