nodes: 0, module; 1, function_definition; 2, function_name:clean_fail; 3, parameters; 4, block; 5, identifier:func; 6, expression_statement; 7, function_definition; 8, return_statement; 9, string; 10, function_name:func_wrapper; 11, parameters; 12, block; 13, identifier:func_wrapper; 14, string_content:A decorator to cleanly exit on a failed call to AWS.
      catch a `botocore.exceptions.ClientError` raised from an action.
      This sort of error is raised if you are targeting a region that
      isn't set up (see, `credstash setup`.; 15, list_splat_pattern; 16, dictionary_splat_pattern; 17, try_statement; 18, identifier:args; 19, identifier:kwargs; 20, block; 21, except_clause; 22, return_statement; 23, as_pattern; 24, block; 25, call; 26, attribute; 27, as_pattern_target; 28, expression_statement; 29, expression_statement; 30, identifier:func; 31, argument_list; 32, attribute; 33, identifier:ClientError; 34, identifier:e; 35, call; 36, call; 37, list_splat; 38, dictionary_splat; 39, identifier:botocore; 40, identifier:exceptions; 41, identifier:print; 42, argument_list; 43, attribute; 44, argument_list; 45, identifier:args; 46, identifier:kwargs; 47, call; 48, keyword_argument; 49, identifier:sys; 50, identifier:exit; 51, integer:1; 52, identifier:str; 53, argument_list; 54, identifier:file; 55, attribute; 56, identifier:e; 57, identifier:sys; 58, identifier:stderr
code: def clean_fail(func):
      '''
      A decorator to cleanly exit on a failed call to AWS.
      catch a `botocore.exceptions.ClientError` raised from an action.
      This sort of error is raised if you are targeting a region that
      isn't set up (see, `credstash setup`.
      '''
      def func_wrapper(*args, **kwargs):
          try:
              return func(*args, **kwargs)
          except botocore.exceptions.ClientError as e:
              print(str(e), file=sys.stderr)
              sys.exit(1)
      return func_wrapper