Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Everything is broken, and I don't know why. Python edition.

Everything is broken, and I don't know why. Python edition.

SF Python
October 12th 2016

Ce86d68173d477a17396b5e611468f52?s=128

Matt Robenolt

October 12, 2016
Tweet

More Decks by Matt Robenolt

Other Decks in Programming

Transcript

  1. Everything is broken, and I don’t know why. Python edition

    SF Python October 12th 2016 Matt Robenolt
  2. Jams Cunningham hello

  3. Core contributor

  4. If an exception happens in production, and nobody sees the

    logs, did it really happen? — Taylor Swift “ ”
  5. Damn Stebe, it works for me. gtfo my inbox. “

    ” — Josh
  6. None
  7. But first, some broken software!

  8. #include <stdio.h> int main () { FILE *fp; char buf[100];

    fp = fopen("foo.txt", "r"); fgets(buf, 100, fp); fclose(fp); } Errors in: C
  9. #include <stdio.h> int main () { FILE *fp; char buf[100];

    fp = fopen("foo.txt", "r"); fgets(buf, 100, fp); fclose(fp); } Errors in: C [1] 53482 segmentation fault ./a.out
  10. #include <stdio.h> int main () { FILE *fp; char buf[100];

    fp = fopen("foo.txt", “r"); if (fp != NULL) { fgets(buf, 100, fp); fclose(fp); } } Errors in: C
  11. package main import "os" func main() { buf := make([]byte,

    100) fp, _ := os.Open("foo.txt") fp.Read(buf) fp.Close() } Errors in: Go
  12. package main import "os" func main() { buf := make([]byte,

    100) fp, _ := os.Open("foo.txt") fp.Read(buf) fp.Close() } Errors in: Go jk nothing happens
  13. package main import "os" func main() { buf := make([]byte,

    100) fp, err := os.Open(“foo.txt") if err == nil { fp.Read(buf) fp.Close() } } Errors in: Go
  14. use std::fs::File; use std::io::Read; fn main() { let mut fp

    = File::open("foo.txt").unwrap(); let mut buf = [0; 100]; fp.read_exact(&mut buf); drop(fp); } Errors in: Rust
  15. use std::fs::File; use std::io::Read; fn main() { let mut fp

    = File::open("foo.txt").unwrap(); let mut buf = [0; 100]; fp.read_exact(&mut buf); drop(fp); } Errors in: Rust thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "No such file or directory" } }', ../src/ libcore/result.rs:788 note: Run with `RUST_BACKTRACE=1` for a backtrace.
  16. use std::fs::File; use std::io::Read; fn main() { match File::open("foo.txt") {

    Ok(mut fp) => { let mut buf = [0; 100]; fp.read_exact(&mut buf); drop(fp); }, Err(_) => { // }, } } Errors in: Rust
  17. fp = open('foo.txt', 'r') buf = fp.read(100) fp.close() Errors in:

    Python
  18. fp = open('foo.txt', 'r') buf = fp.read(100) fp.close() Errors in:

    Python Traceback (most recent call last): File "main.py", line 1, in <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt'
  19. try: fp = open('foo.txt', 'r') except IOError: pass else: buf

    = fp.read(100) fp.close() Errors in: Python
  20. try: fp = open('foo.txt', 'r') except IOError: pass else: buf

    = fp.read(100) fp.close() Errors in: Python Exceptions
  21. Exceptions Errors vs

  22. Errors

  23. Errors Non-fatal, multiple may exist within a call stack at

    the same time, generally returned as a value.
  24. Exceptions Fatal, must be handled, only one exists within a

    call stack, raised to abort current execution.
  25. Exceptions Fatal, must be handled, only one exists within a

    call stack, raised to abort current execution.
  26. Traceback (most recent call last): File "main.py", line 1, in

    <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt'
  27. Traceback (most recent call last): File "main.py", line 1, in

    <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt' So what do we do with this thing?
  28. Traceback (most recent call last): File "main.py", line 1, in

    <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt' So what do we do with this thing? …and where does it come from?
  29. fp = open('foo.txt', 'r') buf = fp.read(100) fp.close()

  30. import sys def excepthook(type, value, tb): print(type, value, tb) sys.excepthook

    = excepthook fp = open('foo.txt', 'r') buf = fp.read(100) fp.close()
  31. import sys def excepthook(type, value, tb): print(type, value, tb) sys.excepthook

    = excepthook fp = open('foo.txt', 'r') buf = fp.read(100) fp.close() (<type 'exceptions.IOError'>, IOError(2, 'No such file or directory'), <traceback object at 0x106810ea8>)
  32. import sys def excepthook(type, value, tb): import traceback traceback.print_exception(type, value,

    tb) sys.excepthook = excepthook fp = open('foo.txt', 'r') buf = fp.read(100) fp.close()
  33. import sys def excepthook(type, value, tb): import traceback traceback.print_exception(type, value,

    tb) sys.excepthook = excepthook fp = open('foo.txt', 'r') buf = fp.read(100) fp.close() Traceback (most recent call last): File "main.py", line 9, in <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt'
  34. fp = open('foo.txt', 'r') buf = fp.read(100) fp.close()

  35. try: fp = open('foo.txt', 'r') except IOError: import sys print(sys.exc_info())

    else: buf = fp.read(100) fp.close()
  36. try: fp = open('foo.txt', 'r') except IOError: import sys print(sys.exc_info())

    else: buf = fp.read(100) fp.close() (<type 'exceptions.IOError'>, IOError(2, 'No such file or directory'), <traceback object at 0x106810ea8>)
  37. try: fp = open('foo.txt', 'r') except IOError: import sys, traceback

    traceback.print_exception(*sys.exc_info()) else: buf = fp.read(100) fp.close()
  38. try: fp = open('foo.txt', ‘r') except IOError: import traceback traceback.print_exc()

    else: buf = fp.read(100) fp.close() Traceback (most recent call last): File "main.py", line 2, in <module> fp = open('foo.txt', 'r') IOError: [Errno 2] No such file or directory: 'foo.txt'
  39. import sys print(sys.exc_info())

  40. import sys print(sys.exc_info()) (None, None, None)

  41. import sys try: raise Exception() except Exception: pass print(sys.exc_info())

  42. import sys try: raise Exception() except Exception: pass print(sys.exc_info()) (None,

    None, None)
  43. try: raise Exception() except Exception: import sys print(sys.exc_info())

  44. try: raise Exception() except Exception: import sys print(sys.exc_info()) (<type 'exceptions.Exception'>,

    Exception(), <traceback object at 0x10ffbec20>)
  45. try: raise Exception() except Exception: import traceback, sys traceback.print_exc(file=sys.stderr)

  46. $ python main.py 2> errors.log

  47. None
  48. $ cat errors.log

  49. $ cat errors.log raise Exception() Exception Traceback (most recent call

    last): File "main.py", line 3, in <module> raise Exception() Exception Traceback (most recent call last): File "main.py", line 3, in <module> raise Exception() Exception Traceback (most recent call last): File "main.py", line 3, in <module> raise Exception() Exception Traceback (most recent call last): File "main.py", line 3, in <module>
  50. $ cat errors.log Traceback (most recent call last): File "main.py",

    line 4, in <module> my_thing = things[key] KeyError: 'thing1' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing2' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing3' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing4'
  51. $ cat errors.log Traceback (most recent call last): File "main.py",

    line 4, in <module> my_thing = things[key] KeyError: 'thing1' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing2' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing3' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing4'
  52. Traceback (most recent call last): File "main.py", line 4, in

    <module> my_thing = things[key] KeyError: 'thing1' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing2' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing3' Traceback (most recent call last): File "main.py", line 4, in <module> my_thing = things[key] KeyError: 'thing4'
  53. Damn Stebe, that variable should be right. You must have

    messed it up. “ ” — Darrell
  54. things = {} key = sys.argv[1] try: my_thing = things[key]

    except KeyError: import traceback traceback.print_exc() print(globals(), locals())
  55. things = {} key = sys.argv[1] try: my_thing = things[key]

    except KeyError: import traceback traceback.print_exc() print(globals(), locals())
  56. things = {} key = sys.argv[1] try: my_thing = things[key]

    except KeyError: import traceback traceback.print_exc() print(globals(), locals()) Traceback (most recent call last): File "main.py", line 5, in <module> things[key] KeyError: 'thing' ({'things': {},'key': 'thing'}, {'things': {}, 'key': 'thing'})
  57. things = {} key = sys.argv[1] try: my_thing = things[key]

    except KeyError: import traceback traceback.print_exc() print(globals(), locals()) Traceback (most recent call last): File "main.py", line 5, in <module> things[key] KeyError: 'thing' ({'things': {},'key': 'thing'}, {'things': {}, 'key': 'thing'})
  58. things = {} key = sys.argv[1] try: my_thing = things[key]

    except KeyError: import traceback, json, sys json.dump({ 'exc': traceback.format_exc(), 'globals': globals(), 'locals': locals(), }, sys.stderr)
  59. things = [0, 1, 2] def get_random_thing(n): return get_thing(randint(0, n))

    def get_thing(index): try: return things[index] except IndexError: print(locals()) get_random_thing(10)
  60. things = [0, 1, 2] def get_random_thing(n): return get_thing(randint(0, n))

    def get_thing(index): try: return things[index] except IndexError: print(locals()) get_random_thing(10) {'index': 8}
  61. def debug(): import sys tb = sys.exc_info()[2] idx = 0

    while tb: idx += 1 frame = tb.tb_frame code = frame.f_code print({ 'line': tb.tb_lineno, 'locals': frame.f_locals, 'function': code.co_name, }) tb = tb.tb_next try: get_random_thing(10) except Exception: debug()
  62. def debug(): import sys tb = sys.exc_info()[2] idx = 0

    while tb: idx += 1 frame = tb.tb_frame code = frame.f_code print({ 'line': tb.tb_lineno, 'locals': frame.f_locals, 'function': code.co_name, }) tb = tb.tb_next try: get_random_thing(10) except Exception: debug() {'function': ‘<module>', 'line': 31, 'locals': {'things': [0, 1, 2]}} {'function': 'get_random_thing', 'line': 7, 'locals': {'n': 4}} {'function': 'get_thing', 'line': 11, 'locals': {'index': 4}}
  63. Hot damn Stebe, thanks for the information. Lemme fix that

    bug for you right away. “ ”
  64. Sentry. Gotta get all dat context.

  65. Questions? I may or may not have answers. @mattrobenolt github.com/mattrobenolt

    sentry.io github.com/getsentry/sentry