Talinon's avatar
Level 51

Random "Network has changed" error

Hello All,

I've been pulling my hair out over this for a couple days. I'll describe my thought process on this.

Back end is LAMP stack, front end is Vue, Axios

I've developed a mobile-first app where a key feature is to submit a photo. Nothing out of the ordinary, just a straight-forward single photo which can be selected or captured by the device's camera.

I received a report that a user was experiencing random error message when trying to submit a photo. On repeated attempts, it would eventually succeed. After extensive testing, here are my findings:

This does NOT happen on my development server, only production. Both production and development are the exact same set up, running under linux.

My first thought was the server rejected photos of high quality/size due to Apache's file or POST size maximum settings within php.ini - this was not the case.

Second thought was validation.. not the case, there is no 422.. in fact, it appears the request never hits the server.

I then discovered that it seems to ONLY be happening on Android devices using Chrome. iPhones do not experience this "random" error, nor does using Firefox on Android.

So, my next thought was to enable Developer Mode on the Android and see what is going on within the developer tools.

Turns out, the device is getting a very uninformative "Network has changed" error. Again, just to hammer it home, this seems completely random. Usually on the next attempt, it succeeds. Sometimes it succeeds on the first attempt.

Reviewing the POST request under the network tab, it shows it requesting the correct HTTPS URL and endpoint. Under Content-Type it shows "multi-part/form-data; boundary=----WebkitFormBoundary(random chars)"

I understand the Boundary is used for separator decoding for the server.. but on successful POST requests, it doesn't have this boundary data.. no idea where this is coming from.

So, I then turned to considering CORS being the culprit. Maybe this error is coming from a pre-flight request to the server. My experience with CORS is limited, but I would think that the pre-flight request would show up in Apache's access log... there is nothing. Which I would expect as it's not actually hitting the server, hence the "Network has changed" error.

To be sure, I applied a wildcard to the request headers for Access-Control-Allow-Origin, added all the methods to Access-Control-Request-Method, etc. Random error still occurs.

The app is running on a sub-domain, but I'm convinced it's not CORS related.. why would it sometimes work if it was CORS? it should be consistently rejected.

This leaves me with only one other guess... the app is running on an intranet behind a Cisco VPN. I'm thinking the VPN is doing something flakey which causes the "random" network error. This would also explain why this does not happen on my test server.

But even if that was true - why does it ONLY happen on multipart POST requests? All other requests are fine.. GET, DELETE, PATCH.. no problems.. only on this file upload does it occur. If there was a network error, you'd think it would happen randomly on any network request. Furthermore, why does Firefox not experience this problem?

I'm starting to think this might be some kind of bug within the Android version of Chrome that is being tripped by the VPN.. I've completely exhausted my brain on this one.. does anyone have any idea what is going on?

As a (temporary?) solution, I've added some automatic re-attempt code to the image upload using AxiosRetry. It seems whatever is causing the "Network has changed" error doesn't stick around for long. It always seems to work on the 2nd or 3rd attempt. The only negative impact of this work-around is the potential for the request to take an additional few seconds to succeed, something I can live with.

Even though this work-around has yet to fail and seems to solve the problem, I'd still love to get to the root of why this is happening...

<v-card
    :class="{ 'on-hover': hover, 'mx-auto': 'mx-auto', 'mt-3': 'mt-3' }"
    max-width="250"
    width="250"
    color="teal darken-4"
    @click="triggerPhoto"
>
<input type="file" ref="createPhoto" accept="image/*" capture v-show=false @change="uploadPhoto($event.target.files, null)">


uploadPhoto(photo, entry) {

    if (!photo.length) return;

    this.loading = true;

    let formData = new FormData();

    let url = entry ? entry.id : '';

    formData.append('photo', photo[0]);
    
    const client = axios.create({ });
    axiosRetry(client, { retries: 5, retryCondition: (_error) => true, retryDelay: (retryCount) => { return retryCount * 2000;  } });

    client.post('/photo/' + url, formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    }).then(response => { 

        flash('Successfully uploaded photo');
        this.fetchEntries();

    }).catch(error => {

        flash('Something went wrong - please try again shortly');


    }).finally(() => {

        this.createDialog = false;
        this.loading = false;
});

triggerPhoto() {

    this.$refs.createPhoto.click()

},

Also, when the error happens, the error object within the catch block is empty.

0 likes
4 replies
jlrdw's avatar

Also see if users who have trouble are using hardwired and Wi-Fi at the same time.

Talinon's avatar
Level 51

Why would an android be hardwired?!

Besides, I described that I confirmed it by testing.

jlrdw's avatar

Android would not be hardwired, I was referring to a user, in home is using Ethernet and wi-fi at the same time.

But I only re-replied since it was asked.

Please or to participate in this conversation.