Created
March 5, 2025 14:50
-
-
Save ulisseshen/db82768bccb532b04ce6a83e7619e136 to your computer and use it in GitHub Desktop.
POC necessário para mostrar o erro [ Null check operator used on a null value] que só aparece em RELEASE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/material.dart'; | |
import 'dart:async'; | |
void main() { | |
// Initialize our error logger before running the app. | |
ErrorLogger.initialize(); | |
runApp(MyApp()); | |
} | |
class ErrorLogger { | |
// Using a ValueNotifier to update the UI whenever the log changes. | |
static final ValueNotifier<String> logNotifier = ValueNotifier<String>(''); | |
static void initialize() { | |
FlutterError.onError = (FlutterErrorDetails details) { | |
// Also append the error to your custom log. | |
ErrorLogger.logNotifier.value += | |
"\n-------------\n" + details.toString() + "\n"; | |
}; | |
// Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics. | |
PlatformDispatcher.instance.onError = (error, stack) { | |
// Also append the error and stack trace to your custom log. | |
ErrorLogger.logNotifier.value += "\n-------------\nError: $error\nStack: $stack\n"; | |
return true; | |
}; | |
} | |
} | |
class CallbackManager { | |
CallbackManager._(); | |
static final CallbackManager instance = CallbackManager._(); | |
/// Registered callback that can be triggered externally. | |
VoidCallback? onCallback; | |
/// Method to trigger the callback if it is registered. | |
void triggerCallback() { | |
if (onCallback != null) { | |
onCallback!(); | |
} | |
} | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Test Callback with Navigation', | |
initialRoute: '/', | |
routes: { | |
'/': (context) => const HomeScreen(), | |
'/dummy': (context) => const DummyScreen(), | |
}, | |
); | |
} | |
} | |
class HomeScreen extends StatelessWidget { | |
const HomeScreen({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Home - CallbackWidget'), | |
), | |
body: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
children: [ | |
const SizedBox(height: 20), | |
// Button to trigger the callback. | |
ElevatedButton( | |
onPressed: () { | |
CallbackManager.instance.triggerCallback(); | |
}, | |
child: const Text('Trigger Callback'), | |
), | |
const SizedBox(height: 20), | |
// Button to navigate to another screen. | |
ElevatedButton( | |
onPressed: () { | |
Navigator.pushNamed(context, '/dummy'); | |
}, | |
child: const Text('Navigate to another screen'), | |
), | |
const SizedBox(height: 20), | |
const Text( | |
'Flutter Error Log:', | |
style: TextStyle(fontWeight: FontWeight.bold), | |
), | |
// The "textarea" displaying errors. | |
Expanded( | |
child: Container( | |
decoration: BoxDecoration( | |
border: Border.all(color: Colors.grey), | |
), | |
width: double.infinity, | |
padding: const EdgeInsets.all(8.0), | |
child: ValueListenableBuilder<String>( | |
valueListenable: ErrorLogger.logNotifier, | |
builder: (context, log, child) { | |
return SingleChildScrollView( | |
child: Text( | |
log, | |
style: const TextStyle(fontSize: 12, color: Colors.red), | |
), | |
); | |
}, | |
), | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
class DummyScreen extends StatefulWidget { | |
const DummyScreen({super.key}); | |
@override | |
State<DummyScreen> createState() => _DummyScreenState(); | |
} | |
class _DummyScreenState extends State<DummyScreen> { | |
bool _callbackFired = false; | |
@override | |
void initState() { | |
super.initState(); | |
// Register a callback that intentionally causes an error by calling setState after dispose. | |
CallbackManager.instance.onCallback = () { | |
Timer(const Duration(seconds: 1), () { | |
// This will trigger an error if the widget has been disposed. | |
setState(() { | |
_callbackFired = true; | |
}); | |
}); | |
}; | |
} | |
@override | |
void dispose() { | |
// Clear the callback to avoid potential errors. | |
// CallbackManager.instance.onCallback = null; | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Dummy Screen'), | |
), | |
body: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
children: [ | |
const Text( | |
'This is a dummy screen.\nThe CallbackWidget has been disposed.', | |
style: TextStyle(fontSize: 20), | |
textAlign: TextAlign.center, | |
), | |
const SizedBox(height: 20), | |
ElevatedButton( | |
onPressed: () { | |
Navigator.pop(context); | |
}, | |
child: const Text('Go Back'), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment