Tools · Web testing tools · 23 / 23
Walkthrough: why Save note loses the text
This pass uses the Network list, Preserve log, the initiator, the request panes, and local storage on one Harbor Ledger bug. The button navigates away before POST /api/notes finishes, and a stale draft can still be sitting in the browser after the server never stored it.
Set the panel up before the click
Start Harbor Ledger on http://127.0.0.1:3000. Use the lab browser profile, signed in as Avery with the seed account. Open DevTools, Network, and turn Preserve log on. Enable the Initiator column. Clear the list so this attempt is the only thing in it. Open Application storage long enough to see whether harbor.draftNote already has text, and write that down so you do not confuse an old draft with this click.
Pick a sentence you have not used: “checked April retainer.” Type it into the note field on invoice 1042. You are about to click once. Everything after this paragraph is reading, until the confirmation at the end.
- Origin: http://127.0.0.1:3000
- Account: Avery
- Preserve log: on
- Initiator column: on
- List: cleared
- Text: a sentence you can search for
One click, then the rows in order
Click Save note. The address bar ends on /invoices. The Network list, because Preserve log is on, still shows the invoice page’s leftovers only if you forgot to clear. The rows from this click are POST /api/notes with status canceled, then the document GET /invoices with status 200, then the list’s API fetch. If you do not see the POST, you cleared too late or Preserve log was off. Do not interpret the destination page as the capture. Set the checkbox and click again with a new sentence.
Select the POST. The response pane is empty. The payload contains your sentence. The initiator is /static/app.js, in the click handler that also assigns the location. Select the document row and see the same file. You now have the cause in one function: it starts the save and leaves the page.
Check the API and the draft key separately
Reload the list and look at GET /api/invoices in the response pane, or open the note list the UI renders from that response. The sentence is absent. That matches a POST the server may never have seen. Then open Application storage for this origin and read harbor.draftNote. The lab script writes the draft as you type, so the sentence may still be there even though the save was canceled. If it is, the form will show it again when you return to the invoice, which feels like the app “remembered” a save it did not keep.
Write both facts. “The list does not show it” is the clerk’s symptom. “The POST was canceled by our own navigation, and the draft key still has the text” is the diagnosis. They point at app.js, not at the database.
POST /api/notes (canceled) payload contains: checked April retainer response pane: empty initiator: /static/app.js GET /api/invoices 200 body does not contain that sentence local storage harbor.draftNote may still contain that sentence
Change the handler, then run the same click
In the lab’s app.js, change the click handler so it waits for the POST to finish, navigates to the list only if that succeeded, and removes harbor.draftNote after success. Leave the failure on the invoice page if the POST fails, so a real server error is visible instead of a silent navigation. This is your app, on loopback, and the change is ordinary front-end control flow.
Hard-reload so the browser fetches the new script. Clear the Network list. Type a new sentence. Click once. POST /api/notes should complete with a real status code, initiator still the script, response pane no longer empty. The following navigation can still be initiated by app.js, and that is fine, because it happens after the response. The list’s JSON contains the sentence. The draft key is gone. Put this capture under the first one. The difference is the regression test.
Worked case: the note you can hand to yourself
Fill the bug-note block from this lesson’s diagram with the before-capture and a second copy with the after-capture. A reader who has the lab can repeat it without your session cookie, because the steps sign in as Avery from the seed account and quote paths rather than cookies. A reader who does not have the lab can still see that you separated a canceled request, a script initiator, an empty response, a missing API row, and a local draft.
Stop there. The bug was a race in a click handler and a draft key that outlived the account’s intent. Nothing in the capture asks you to send the note text to any host but the one you are running, and nothing in it gets clearer if you add a scanner. The panels were sufficient.
Diagram
Five checks, one click
- Setup
Lab profile, http://127.0.0.1:3000, signed in as Avery, DevTools open, Preserve log on, list cleared.
- Click
Type a fresh note and click Save note once. The list keeps a canceled POST and then a document load of /invoices.
- Cause
Both rows are initiated by the click handler in /static/app.js. The response pane of the POST is empty.
- Stores
The sentence is absent from the API, and it may still be present in harbor.draftNote. The fix waits for the POST before navigating.
Two stories about the same button
Evidence. The list page does not show the note.
Unused. Preserve log, initiator, and the empty response pane.
Change. You rewrite the API.
Evidence. POST /api/notes is canceled. Initiator is app.js. Response pane is empty.
Also. Local storage may still hold the draft. The API list does not.
Change. The handler awaits the POST, then navigates, and the draft key is cleared on success.
Page: http://127.0.0.1:3000/invoices/1042 Account: Avery (seed) Browser: lab profile Preserve log: on Click: Save note, text "checked April retainer" Row: POST /api/notes Status column: (canceled) Response pane: empty Initiator: /static/app.js click handler Next row: GET /invoices 200, same initiator API after reload: text absent local storage harbor.draftNote: may still hold the text Change: navigate only after the POST completes, then clear the draft key
Check yourself
1. Which capture shows that Save note aborted its own request?
2. The API does not contain the sentence, and local storage still does. What should the note say?
3. After you change the click handler to wait for the POST, which result means the bug is gone?
4. Where does this walkthrough send traffic?