Add some more rigorous error handling.

Also, attempts to avoid a string allocation by using slice() instead of replace(). (Who knows if JS will actually avoid the allocation, but it should if it's smart.)