web analytics

Flutter : รู้จักกับ Sentry เครื่องมือสำหรับรายงาน Error ในแอป

cover

 

สวัสดีผู้อ่านครับ ช่วงนี้ผมก็หาอะไรเล่นไปเรื่อยๆ ไปเจอในเว็บ Flutter ที่แนะนำเรื่อง Crash Reporting โดยใช้เครื่องมือที่ชื่อว่า Sentry นั่นก็เพราะว่า Sentry ได้ทำ library สำหรับ Flutter สำหรับผู้ที่ไม่ทราบว่า Crash Reporting  คืออะไร มันก็คือการรายงาน error ของแอปจากเครื่องผู้ใช้ไปที่เว็บ เพื่อให้เราตรวจสอบและแก้ไขปัญหาได้ทันที เพราะว่าเราคงไม่สามารถเดินไปหาผู้ใช้แอปแล้วขอมือถือมาแก้ error ได้แน่ๆ ดังนั้นเลยมีผู้ให้บริการหลายเจ้าพัฒนาเครื่องมือมาเพื่อช่วยแก้ปัญหา ซึ่งเจ้าดังๆที่ผมเคยใช้ก็มี Crashlytic (ตอนนี้ถูก Google ซื้อไปรวมกับ Firebase) ส่วน Sentry ผมก็เพิ่งเคยได้ยิน วันนี้เลยถือโอกาสลองใช้งานกันครับ

 

เริ่มต้น

สม้ครใช้งาน https://sentry.io/ จากนั้นก็ sign in
แล้วก็สร้าง project

1

 

แล้วเราก็จะได้โค้ด DSN เอาไว้ระบุตัวตนของแอปเรา

2a

 

 

การใช้งาน Sentry ใน Flutter

เพิ่ม dependencies ใน pubspec.yaml

dependencies:
  sentry: 2.2.0

 

import sentry เข้ามาที่ main.dart หรือไฟล์ที่ต้องการ Crash reporting

import 'package:sentry/sentry.dart';

 

ประกาศ SentryClient พร้อมกับระบุ DSN ของเราให้มัน

  final SentryClient sentry =  SentryClient(dsn: "....");

 

ทดลองทำหน้าจอ เมื่อกดปุ่มแล้วจะส่ง error ไปที่ Sentry

class MyHomePage extends StatelessWidget {

  final SentryClient sentry =  SentryClient(dsn: "...");

  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("My Sentry App"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FlatButton(color: Colors.blue[100],child: Text("Get error"),onPressed: (){
              displayError();
            },)
          ],
        ),
      ),
    );
  }

  void displayError() async{
      try {
        throw  StateError('This is an async Dart exception.');
      } catch(error, stackTrace) {
        await sentry.captureException(
          exception: error,
          stackTrace: stackTrace,
        );
        print("Sent error to Sentry.io ,"+error.toString());
      }
  }
}

8

 

การดูรายงาน

เสร็จแล้วไปที่เว็บ sentry ที่เมนู Issues ก็จะมี error ของเราปรากฏ

4

 

อันไหนเราแก้ไขแล้วก็ติ๊ก แล้วกดที่ Resolve ได้เลย

6

 

 แยก DebugMode กับ Production

เราคงไม่อยากให้ ระหว่างที่เรา debug แล้วเกิด error แอปส่ง report ไปที่ sentry ปนกับของ Production
ดังนั้นเราควรแยกให้ debugMode แค่ print log ก็พอ

สร้าง method สำหรับเช็คว่าเป็น DebugMode หรือไม่
กรณี Production ให้ comment บรรทัด assert ออก

bool get isInDebugMode {
  bool inDebugMode = false;
  assert(inDebugMode = true);
  return inDebugMode;
}

 

 

เขียน method สำหรับส่ง report error เพื่อให้ใช้งานง่ายขึ้น

  Future<Null> reportErrorToSentry(dynamic error, dynamic stackTrace) async{
    if (isInDebugMode) {
      print(stackTrace);
      return;
    }
    
    sentry.captureException(
      exception: error,
      stackTrace: stackTrace,
    );
  }

 

method ตอนกดปุ่มของเราจะเหลือแค่นี้

  void displayError() async {
    try {
      throw StateError('This is an async Dart exception.');
    } catch (error, stackTrace) {
      reportErrorToSentry(error , stackTrace);
    }
  }

 

ดัก Error จากทั้งแอป

การใช้ try catch ดักทีละเคสก็อาจจะเหนื่อยเกินไป เราสามารถใช้ Zone มาครอบแอปของเราได้ โดยเมื่อจุดใดๆในแอปของเรา เกิด error มันจะเข้า onError

Future<Null> main() async {
  FlutterError.onError = (FlutterErrorDetails details) async {
    if (isInDebugMode) {
      FlutterError.dumpErrorToConsole(details);
    } else {
      Zone.current.handleUncaughtError(details.exception, details.stack);
    }
  };

  runZoned<Future<Null>>(() async {
    runApp(new MyApp());
  }, onError: (error, stackTrace) async {
    await reportError(error, stackTrace);
  });
}

 

ราคาค่าบริการของ Sentry

ดูราคาของ sentry ได้ที่ https://sentry.io/pricing/
หลักๆคือ Developer plan จะฟรี แต่รับ error ได้แค่ 5,000 event ต่อเดือน เก็บประวัติ 30 วัน

7