Last active
          November 26, 2019 23:26 
        
      - 
      
 - 
        
Save redbrogdon/e221e3fd667825e62aac79079b8b5c59 to your computer and use it in GitHub Desktop.  
    DartPad Cheetsheet Codelab - 10 - Exceptions
  
        
  
    
      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
    
  
  
    
  | This exercise looks tricky, but it's really one big `try` statement. | |
| Just call `untrustworthy` inside the `try`, and then use `on`, `catch`, | |
| and `finally` to catch exceptions and call methods on the logger. | 
  
    
      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
    
  
  
    
  | typedef VoidFunction = void Function(); | |
| class ExceptionWithMessage { | |
| final String message; | |
| const ExceptionWithMessage(this.message); | |
| } | |
| // Call logException to log an exception, and doneLogging when finished. | |
| abstract class Logger { | |
| void logException(Type t, [String msg]); | |
| void doneLogging(); | |
| } | |
| void tryFunction(VoidFunction untrustworthy, Logger logger) { | |
| // Invoking this method might cause an exception. Catch and handle | |
| // them using try-on-catch-finally. | |
| untrustworthy(); | |
| } | 
  
    
      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
    
  
  
    
  | typedef VoidFunction = void Function(); | |
| class ExceptionWithMessage { | |
| final String message; | |
| const ExceptionWithMessage(this.message); | |
| } | |
| abstract class Logger { | |
| void logException(Type t, [String msg]); | |
| void doneLogging(); | |
| } | |
| void tryFunction(VoidFunction untrustworthy, Logger logger) { | |
| try { | |
| untrustworthy(); | |
| } on ExceptionWithMessage catch (e) { | |
| logger.logException(e.runtimeType, e.message); | |
| } on Exception { | |
| logger.logException(Exception); | |
| } finally { | |
| logger.doneLogging(); | |
| } | |
| } | 
  
    
      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
    
  
  
    
  | class MyLogger extends Logger { | |
| Type lastType; | |
| String lastMessage = ''; | |
| bool done = false; | |
| void logException(Type t, [String message]) { | |
| lastType = t; | |
| lastMessage = message ?? lastMessage; | |
| } | |
| void doneLogging() => done = true; | |
| } | |
| void main() { | |
| final errs = <String>[]; | |
| var logger = MyLogger(); | |
| try { | |
| tryFunction(() => throw Exception(), logger); | |
| if ('${logger.lastType}' != 'Exception' && '${logger.lastType}' != '_Exception') { | |
| errs.add('Untrustworthy threw an Exception, but a different type was logged: ${logger.lastType}.'); | |
| } | |
| if (logger.lastMessage != '') { | |
| errs.add('Untrustworthy threw an Exception with no message, but a message was logged anyway: \'${logger.lastMessage}\'.'); | |
| } | |
| if (!logger.done) { | |
| errs.add('Untrustworthy threw an Exception, and doneLogging() wasn\'t called afterward.'); | |
| } | |
| } catch (e) { | |
| _result(false, ['Untrustworthy threw an exception, and an exception of type ${e.runtimeType} was unhandled by tryFunction.']); | |
| } | |
| logger = MyLogger(); | |
| try { | |
| tryFunction(() => throw ExceptionWithMessage('Hey!'), logger); | |
| if (logger.lastType != ExceptionWithMessage) { | |
| errs.add('Untrustworthy threw an ExceptionWithMessage(\'Hey!\'), but a different type was logged: ${logger.lastType}.'); | |
| } | |
| if (logger.lastMessage != 'Hey!') { | |
| errs.add('Untrustworthy threw an ExceptionWithMessage(\'Hey!\'), but a different message was logged: \'${logger.lastMessage}\'.'); | |
| } | |
| if (!logger.done) { | |
| errs.add('Untrustworthy threw an ExceptionWithMessage(\'Hey!\'), and doneLogging() wasn\'t called afterward.'); | |
| } | |
| } catch (e) { | |
| _result(false, ['Untrustworthy threw an ExceptionWithMessage(\'Hey!\'), and an exception of type ${e.runtimeType} was unhandled by tryFunction.']); | |
| } | |
| logger = MyLogger(); | |
| bool caughtStringException = false; | |
| try { | |
| tryFunction(() => throw 'A String', logger); | |
| } on String { | |
| caughtStringException = true; | |
| } | |
| if (!caughtStringException) { | |
| errs.add('Untrustworthy threw a string, and it was incorrectly handled inside tryFunction().'); | |
| } | |
| logger = MyLogger(); | |
| try { | |
| tryFunction(() {}, logger); | |
| if (logger.lastType != null) { | |
| errs.add('Untrustworthy didn\'t throw an Exception, but one was logged anyway: ${logger.lastType}.'); | |
| } | |
| if (logger.lastMessage != '') { | |
| errs.add('Untrustworthy didn\'t throw an Exception with no message, but a message was logged anyway: \'${logger.lastMessage}\'.'); | |
| } | |
| if (!logger.done) { | |
| errs.add('Untrustworthy didn\'t throw an Exception, but doneLogging() wasn\'t called afterward.'); | |
| } | |
| } catch (e) { | |
| _result(false, ['Untrustworthy didn\'t throw an exception, but an exception of type ${e.runtimeType} was unhandled by tryFunction anyway.']); | |
| } | |
| if (errs.isEmpty) { | |
| _result(true); | |
| } else { | |
| _result(false, errs); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment