getsentry / sentry-dart

Sentry SDK for Dart and Flutter
https://sentry.io/for/flutter/
MIT License
752 stars 234 forks source link

Unable to extract source maps from dependencies when native exception occurs #2343

Open Masadow opened 6 days ago

Masadow commented 6 days ago

Platform

Flutter Web

Obfuscation

Enabled

Debug Info

Enabled

Doctor

Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.24.3, on macOS 14.1.1 23B81 darwin-x64, locale en-FR) [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 15.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2022.3) [✓] VS Code (version 1.94.0) [✓] Connected device (2 available) [✓] Network resources

• No issues found!

Version

8.9.0

Steps to Reproduce

I don't have a clue on how to reproduce since I cannot identify the error at all

Image Image Image

Expected Result

I should be able to see the source code for my own code at least. You can see in the stacktrace that there are some part that matches my flutter application.

It's only this specific issue that causing troubles, other issues are showing stacktraces correctly

Actual Result

I can't see anything aside from the exception message

Image Image

Are you willing to submit a PR?

None

buenaflor commented 5 days ago

hey can you provide more info on your setup, which packages do you use? is this somehow related to wasm? I'm confused why there's native code in a flutter web app

Masadow commented 5 days ago

I've tweaked my index.html to include a loader + amplitude SDK as you can see below

The app can be used in kiosk mode so behaviour changes depending on whether or not we're on an android device, for that I rely on kIsWeb and Platform.isAndroid

Aside from that, the rest is very standard

<!DOCTYPE html>
<html>
<head>
  <!--
    If you are serving your web app in a path other than the root, change the
    href value below to reflect the base path you are serving from.

    The path provided below has to start and end with a slash "/" in order for
    it to work correctly.

    For more details:
    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

    This is a placeholder for base href that will be replaced by the value of
    the `--base-href` argument provided to `flutter build`.
  -->
  <base href="$FLUTTER_BASE_HREF">

  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="Medami est un questionnaire de santé intelligent pour rendre acteurs de votre santé et vous offrir une meilleure prise en charge par votre praticien.">

  <!-- iOS meta tags & icons -->
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="medami_patient">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <!-- Favicon -->
  <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
  <link rel="icon" href="favicon.ico" type="image/x-icon">

  <title>Medami - Votre questionnaire de santé intelligent</title>
  <link rel="manifest" href="manifest.json">

  <script type="text/javascript" defer>
    (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script")
     ;r.type="text/javascript"
     ;r.integrity="sha384-UcvEbHmT0LE2ZB30Y3FmY3Nfw6puAKXz/LpCFuoywywYikMOr/519Uu1yNq2nL9w"
     ;r.crossOrigin="anonymous";r.async=true
     ;r.src="https://cdn.amplitude.com/libs/amplitude-8.12.0-min.gz.js"
     ;r.onload=function(){if(!e.amplitude.runQueuedFunctions){
     console.log("[Amplitude] Error: could not load SDK")}}
     ;var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(r,s)
     ;function i(e,t){e.prototype[t]=function(){
     this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this}}
     var o=function(){this._q=[];return this}
     ;var a=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove"]
     ;for(var c=0;c<a.length;c++){i(o,a[c])}n.Identify=o;var u=function(){this._q=[]
     ;return this}
     ;var l=["setProductId","setQuantity","setPrice","setRevenueType","setEventProperties"]
     ;for(var p=0;p<l.length;p++){i(u,l[p])}n.Revenue=u
     ;var d=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","enableTracking","setGlobalUserProperties","identify","clearUserProperties","setGroup","logRevenueV2","regenerateDeviceId","groupIdentify","onInit","logEventWithTimestamp","logEventWithGroups","setSessionId","resetSessionId","getDeviceId","getUserId","setMinTimeBetweenSessionsMillis","setEventUploadThreshold","setUseDynamicConfig","setServerZone","setServerUrl","sendEvents","setLibrary","setTransport"]
     ;function v(e){function t(t){e[t]=function(){
     e._q.push([t].concat(Array.prototype.slice.call(arguments,0)))}}
     for(var n=0;n<d.length;n++){t(d[n])}}v(n);n.getInstance=function(e){
     e=(!e||e.length===0?"$default_instance":e).toLowerCase()
     ;if(!Object.prototype.hasOwnProperty.call(n._iq,e)){n._iq[e]={_q:[]};v(n._iq[e])
     }return n._iq[e]};e.amplitude=n})(window,document);
  </script>

<!-- This script adds the flutter initialization JS code -->
  <script src="flutter.js" defer></script>

  <link rel="stylesheet" href="loader.css" />
</head>
<body>
  <div class="loader-container">
    <img class="logo" src="icons/logo.png" />

    <div class="loader">
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
      <div class="dot"></div>
    </div>
  </div>

  <script src="flutter_bootstrap.js" async></script>
</body>
</html>

Loader is then hidden with :

void hideLoader() {
  if (kIsWeb && !loaderHidden) {
    (html.window.document.getElementsByClassName('loader-container').first
            as html.Element)
        .classes
        .add('hide');
    loaderHidden = true;
  }
}

Also, html library is imported as :

import 'package:medami_patient/src/utils/fake_html.dart'
    if (dart.library.html) 'dart:html' as html;

with fake_html.dart just being a dummy to allow code to compile on android

// This package is intended to provide a cross platform alternative to import dart:html

late dynamic window;
typedef Element = dynamic;