Repository: openstates/openstates-scrapers

Issue:
WA failing since at least 2017-12-02
WA has been failing since 2017-12-02

Based on automated runs it appears that WA has not run successfully in 2 days (2017-12-02).


```
  05:08:57 INFO pupa: save person Annette Cleveland as person_5bae4a7a-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5bae4a7a-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "upper"} as membership_5bae4d54-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5bae4a7a-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "party", "name": "Democratic"} as membership_5bae4f52-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save person Steve Conway as person_5baed576-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5baed576-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "upper"} as membership_5baed9ea-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5baed576-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "party", "name": "Democratic"} as membership_5baedc4c-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save person Jeannie Darneille as person_5baf5dde-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5baf5dde-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "upper"} as membership_5baf60b8-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save membership 5baf5dde-d81a-11e7-9f94-0242ac110003 membership in ~{"classification": "party", "name": "Democratic"} as membership_5baf62b6-d81a-11e7-9f94-0242ac110003.json
05:08:57 INFO pupa: save person Manka Dhingra as person_5bafe70e-d81a-11e7-9f94-0242ac110003.json
  committees: {}
no pupa_settings on path, using defaults
wa (scrape, import)
  bills: {}
  people: {}
    raise ve
  File "/opt/openstates/venv-pupa//bin/pupa", line 11, in <module>
    load_entry_point('pupa', 'console_scripts', 'pupa')()
  File "/opt/openstates/venv-pupa/src/pupa/pupa/cli/__main__.py", line 67, in main
    subcommands[args.subcommand].handle(args, other)
  File "/opt/openstates/venv-pupa/src/pupa/pupa/cli/commands/update.py", line 260, in handle
    return self.do_handle(args, other, juris)
  File "/opt/openstates/venv-pupa/src/pupa/pupa/cli/commands/update.py", line 305, in do_handle
    report['scrape'] = self.do_scrape(juris, args, scrapers)
  File "/opt/openstates/venv-pupa/src/pupa/pupa/cli/commands/update.py", line 173, in do_scrape
    report[scraper_name] = scraper.do_scrape(**scrape_args)
  File "/opt/openstates/venv-pupa/src/pupa/pupa/scrape/base.py", line 116, in do_scrape
    self.save_object(obj)
  File "/opt/openstates/venv-pupa/src/pupa/pupa/scrape/base.py", line 99, in save_object
Traceback (most recent call last):
  File "/opt/openstates/venv-pupa/src/pupa/pupa/scrape/base.py", line 96, in save_object
    obj.validate()
  File "/opt/openstates/venv-pupa/src/pupa/pupa/scrape/base.py", line 191, in validate
    self.__class__.__name__, self._id, '\n\t'+'\n\t'.join(errors)
pupa.exceptions.ScrapeValueError: validation of Person 5bafe70e-d81a-11e7-9f94-0242ac110003 failed: 
	None is not of type 'string'
Failed validating 'type' in schema['properties']['contact_details']['items']['properties']['value']:
    {'minLength': 1, 'type': 'string'}
On instance['contact_details'][0]['value']:
    None
	'' is too short
Failed validating 'minLength' in schema['properties']['contact_details']['items']['properties']['value']:
    {'minLength': 1, 'type': 'string'}
On instance['contact_details'][1]['value']:
    ''
	None is not of type 'string'
Failed validating 'type' in schema['properties']['contact_details']['items']['properties']['value']:
    {'minLength': 1, 'type': 'string'}
On instance['contact_details'][2]['value']:
    None
```

Visit http://bobsled.openstates.org for more info.



Discussion:

Resolving patch:
diff --git a/openstates/wa/people.py b/openstates/wa/people.py
--- a/openstates/wa/people.py
+++ b/openstates/wa/people.py
@@ -79,14 +79,18 @@ def scrape_chamber(self, index_url, chamber):
                     district_num,
                     position)).strip()
 
-            leg.add_contact_detail(type='address', value=capitol_address,
-                                   note='Capitol Office')
-            leg.add_contact_detail(type='email', value=email,
-                                   note='Capitol Office')
-            leg.add_contact_detail(type='voice', value=capitol_phone,
-                                   note='Capitol Office')
-            leg.add_contact_detail(type='fax', value=str(capitol_fax),
-                                   note='Capitol Office')
+            if capitol_address:
+                leg.add_contact_detail(type='address', value=capitol_address,
+                                       note='Capitol Office')
+            if email:
+                leg.add_contact_detail(type='email', value=email,
+                                       note='Capitol Office')
+            if capitol_phone:
+                leg.add_contact_detail(type='voice', value=capitol_phone,
+                                       note='Capitol Office')
+            if capitol_fax:
+                leg.add_contact_detail(type='fax', value=str(capitol_fax),
+                                       note='Capitol Office')
             _has_district_office = member.xpath('.//div[@class="memberColumnTitle" and'
                                                 'text()=" District Office"]')
             if _has_district_office:
@@ -107,11 +111,13 @@ def scrape_chamber(self, index_url, chamber):
                 except AssertionError:
                     pass
 
-                leg.add_contact_detail(type='voice', value=district_phone,
-                                       note='District Office')
+                if district_phone:
+                    leg.add_contact_detail(type='voice', value=district_phone,
+                                           note='District Office')
 
-                leg.add_contact_detail(type='address', value=district_address,
-                                       note='District Office')
+                if district_address:
+                    leg.add_contact_detail(type='address', value=district_address,
+                                           note='District Office')
             leg.add_source(index_url)
             leg.add_link(index_url)
             yield leg


Test patch: