Skip to content

Support for user feedback #215

@ueman

Description

@ueman

I would like to request support for Sentry's User Feedback.

I see at least two possibilities on how to do this:

Proposal 1:

By providing a more elaborate SentryFlutter.captureException like for example:

SentryFlutter.captureException(
  exception: error,
  stackTrace: stackTrace,
  context: context, // this is a BuildContext
);

With a BuildContext one can show a dialog (see showDialog) which can be used to gather the user's feedback.

Proposal 2:

Another option would be by overriding ErrorWidget.builder (aka Flutter's infamous Red Screen of Death).
This way one could could also capture and report the errors which get passed into ErrorWidget.builder. These are errors
which are happening during the creation of the UI.

An example (more or less pseudo code):

// We assume SentryOptions has a ErrorWidgetBuilder named errorWidgetBuilder which can be defined by the user.
// By providing the same callback it is easy to migrate to this.

class UserFeedback {
  // ...
}

class UserFeedbackErrorWidget extends StatefulWidget {
  const YellowBird({ Key key, this.details, this.options }) : super(key: key);

  final FlutterErrorDetails details;
  final SentryOptions options;

  @override
  _UserFeedbackErrorWidgetState createState() => _UserFeedbackErrorWidgetState();
}

class _UserFeedbackErrorWidgetState extends State<UserFeedbackErrorWidget> {

  @override
  void initState(){
    super.initState();
    // one can't open a dialog in initState
    // see https://stackoverflow.com/questions/51766977/flutter-showdialogcontext-in-initstate-method
   Future.delayed(Duration.zero, askForUserFeedback)
  }

  @override
  Widget build(BuildContext context) {
    // This way a user defined widget is shown inline in the ui.
    // It's nice for the user, because it is not very intrusive.
    return options.errorWidgetBuilder(widget.details);
  }

  Future<void> askForUserFeedback() {
    final error = widget.details;
    final sentryId = await Sentry.captureException(error);

    // showDialog returns what is given to Navigator.pop(...)
    final feedback = await showDialog<UserFeedback>(context, (innerContext){ 
      // show dialog, where the user can input additional information and return it
     return UserFeedbackDialog(
       onSubmit: (feedback) => Navigator.pop(innerContext, feedback)
     );
    });
    await Sentry.sendFeedback(sentryId, feedback);
  }
}

Now we can set ErrorWidget.builder inside an Integration with

ErrorWidget.builder = (FlutterErrorDetails details) => UserFeedbackErrorWidget(details: details, options: sentryOptions);

I guess providing both options would be optimal.

If there are any questions, I'm happy to help.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions