uppy/packages/@uppy
Copilot 46f81e2bae
Fix isNetworkError to match MDN spec: readyState === 4 && status === 0 (#6050)
closes #4253

The `isNetworkError` function incorrectly classified XHR states as
network errors. Per MDN, a network error occurs when a request completes
(`readyState === 4`) but has no HTTP status (`status === 0`), indicating
network/CORS/file access failures.

## Changes

- **Logic fix**: Changed from `(xhr.readyState !== 0 && xhr.readyState
!== 4) || xhr.status === 0` to `xhr.readyState === 4 && xhr.status ===
0`
- **Test update**: Removed invalid test expecting `readyState: 2` to be
a network error; added test verifying incomplete requests return `false`

## Example

```typescript
// Before: incorrectly treated in-progress requests as network errors
isNetworkError({ readyState: 2, status: 0 })  // true 

// After: only completed requests with no status are network errors  
isNetworkError({ readyState: 4, status: 0 })  // true ✓
isNetworkError({ readyState: 2, status: 0 })  // false ✓
```

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> Update the isNetworkError function in
packages/@uppy/utils/src/isNetworkError.ts to correctly detect network
errors according to MDN documentation. The new logic should return true
only if xhr.readyState === 4 and xhr.status === 0. The updated
implementation should be:
> 
> function isNetworkError(xhr?: XMLHttpRequest): boolean {
>   if (!xhr) return false
> // finished but status is 0 — usually indicates a network/CORS/file
error
>   return xhr.readyState === 4 && xhr.status === 0
> }
> 
> export default isNetworkError
> 
> No other logic changes are needed. If you find related commentary
(e.g., outdated comments), clarify as needed.


</details>

*This pull request was created as a result of the following prompt from
Copilot chat.*
> Update the isNetworkError function in
packages/@uppy/utils/src/isNetworkError.ts to correctly detect network
errors according to MDN documentation. The new logic should return true
only if xhr.readyState === 4 and xhr.status === 0. The updated
implementation should be:
> 
> function isNetworkError(xhr?: XMLHttpRequest): boolean {
>   if (!xhr) return false
> // finished but status is 0 — usually indicates a network/CORS/file
error
>   return xhr.readyState === 4 && xhr.status === 0
> }
> 
> export default isNetworkError
> 
> No other logic changes are needed. If you find related commentary
(e.g., outdated comments), clarify as needed.

<!-- START COPILOT CODING AGENT TIPS -->
---

 Let Copilot coding agent [set things up for
you](https://github.com/transloadit/uppy/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mifi <402547+mifi@users.noreply.github.com>
2025-11-05 13:06:21 +08:00
..
angular [ci] release (#6029) 2025-10-28 10:15:14 +01:00
audio [ci] release (#5939) 2025-09-16 16:07:17 +02:00
aws-s3 [ci] release (#6011) 2025-10-17 20:24:52 +02:00
box [ci] release (#5939) 2025-09-16 16:07:17 +02:00
companion [ci] release (#6049) 2025-11-03 14:26:07 +01:00
companion-client [ci] release (#6011) 2025-10-17 20:24:52 +02:00
components [ci] release (#6029) 2025-10-28 10:15:14 +01:00
compressor [ci] release (#6011) 2025-10-17 20:24:52 +02:00
core [ci] release (#6011) 2025-10-17 20:24:52 +02:00
dashboard [ci] release (#6049) 2025-11-03 14:26:07 +01:00
drag-drop [ci] release (#5939) 2025-09-16 16:07:17 +02:00
drop-target [ci] release (#5939) 2025-09-16 16:07:17 +02:00
dropbox Server side search @uppy/Companion (#6003) 2025-10-08 21:18:17 +02:00
facebook [ci] release (#5939) 2025-09-16 16:07:17 +02:00
form [ci] release (#5939) 2025-09-16 16:07:17 +02:00
golden-retriever Fix various deps and peer deps in packages (#6030) 2025-10-28 09:55:21 +01:00
google-drive [ci] release (#5939) 2025-09-16 16:07:17 +02:00
google-drive-picker [ci] release (#5939) 2025-09-16 16:07:17 +02:00
google-photos-picker [ci] release (#5939) 2025-09-16 16:07:17 +02:00
image-editor [ci] release (#6011) 2025-10-17 20:24:52 +02:00
instagram [ci] release (#5939) 2025-09-16 16:07:17 +02:00
locales Revert "[ci] release (#5973)" 2025-09-26 11:30:56 +02:00
onedrive [ci] release (#6029) 2025-10-28 10:15:14 +01:00
provider-views [ci] release (#6046) 2025-10-30 10:10:59 +01:00
react [ci] release (#6046) 2025-10-30 10:10:59 +01:00
remote-sources [ci] release (#5939) 2025-09-16 16:07:17 +02:00
screen-capture [ci] release (#5939) 2025-09-16 16:07:17 +02:00
status-bar [ci] release (#6027) 2025-10-22 21:21:09 +02:00
store-default [ci] release (#5918) 2025-08-22 09:02:12 +02:00
svelte [ci] release (#6029) 2025-10-28 10:15:14 +01:00
thumbnail-generator [ci] release (#6011) 2025-10-17 20:24:52 +02:00
transloadit [ci] release (#6029) 2025-10-28 10:15:14 +01:00
tus [ci] release (#6011) 2025-10-17 20:24:52 +02:00
unsplash [ci] release (#5939) 2025-09-16 16:07:17 +02:00
url [ci] release (#6011) 2025-10-17 20:24:52 +02:00
utils Fix isNetworkError to match MDN spec: readyState === 4 && status === 0 (#6050) 2025-11-05 13:06:21 +08:00
vue [ci] release (#6029) 2025-10-28 10:15:14 +01:00
webcam [ci] release (#6027) 2025-10-22 21:21:09 +02:00
webdav [ci] release (#5939) 2025-09-16 16:07:17 +02:00
xhr-upload [ci] release (#6027) 2025-10-22 21:21:09 +02:00
zoom [ci] release (#5939) 2025-09-16 16:07:17 +02:00