I noticed that you don't check entities or surfaces for validity basically anywhere, which is going to break your code. Not quickly, but inevitably.
For everything that has a .valid field, which is pretty much anything from the Factorio API, make sure you check thing and thing.valid before you touch anything else on the object -- reading fields, or calling methods.
(also .valid_for_read if you want the content of something, which isn't relevant here, but seems worth mentioning overall.)