Reorganize the read() algorithm

- Less indentation
- The same ordering and handle-error-first as cancel(reason)