Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

Node.JS Failed fetch

CaptainHoola

New Coder
Hello,

I've created a audio recorder for my website which lets the user send a recording to a google drive account. At the moment i'm running this on a local environment before i deploy online. For all intents and purpose, everything seems to be running as expected. The user records audio, clicks upload then i receive the file in the google drive account. However, i'm getting the following error once the Upload button is pressed:
main.js:133 Error during upload: Stack: TypeError: Failed to fetch
at HTMLButtonElement.<anonymous> (http://127.0.0.1:5500/main.js:116:32)

Any ideas?

Thanks,

line116 = line24,
line133 = line41,
FRONTEND
JavaScript:
uploadBtn.addEventListener('click', async function() {
    // Ensure there is an audio file to upload
    if (!playback.src) {
        alert('No recording found. Please record audio before uploading.');
        return;
    }

    // Log playback source for debugging
    console.log('playback.src:', playback.src);

    try {
        // Fetch the blob from the playback source
        const blob = await fetch(playback.src).then(res => res.blob());
        console.log('Blob fetched successfully:', blob);

        const formData = new FormData();
        const timestamp = new Date().toISOString().replace(/[:.-]/g, ''); // Unique filename
        const filename = `recording_${timestamp}.ogg`;  // Use .ogg format to match the type
        formData.append('file', blob, filename);

        console.log('FormData prepared:', [...formData.entries()]);

        // Send the blob to the backend server
        const response = await fetch('http://localhost:3000/upload', {
            method: 'POST',
            body: formData,
        });

        if (!response.ok) {
            const errorText = await response.text(); // Get the response text to debug
            throw new Error('Server responded with status ' + response.status+ ': ' + errorText);
        }

        const data = await response.json();
        console.log('Upload successful:', data);
        
        alert('Upload successful! File ID: ' + data.fileId);

    } catch (error) {
        // Log error message and stack trace for debugging
        console.error('Error during upload:', error, 'Stack:', error.stack);
        alert('An error occurred during the upload: ' + error.message);
    }
});

BACKEND
JavaScript:
// Respond with the file ID
const responseData = { fileId: response.data.id };
console.log('Response to be sent:', responseData); // Log the response data
      res.status(200).json({ fileId: response.data.id }); // Respond with the file ID
  } catch (error) {
      console.error('Error during file upload:', error);
      res.status(500).json({ message: 'Failed to upload file.', error: error.message });
  }
});
 
Just to make sure, do you have a server running on port 3000? Because in your error message, you seem to be running the website on port 5500.
 
I'm running live server in VSC on port 5500 and my backend is running on 3000. I have CORS configured also. It's just the fact that apart from this error popping up, the upload process is working fine.
 
Hey there!
The "Failed to fetch" error usually means there’s an issue with your frontend talking to the backend. First, double-check that your backend is running at http://localhost:3000/upload and that it’s accessible. If it’s all good, the problem could be a CORS issue—browsers block requests between different origins sometimes, so adding CORS support in your backend might help. Just throw in something like this:
JavaScript:
const cors = require('cors');
app.use(cors());
Another thing to check is the blob URL (playback.src). Make sure it’s valid and hasn’t expired before you try fetching it. Also, if your frontend is on https:// and your backend is on http://, that mismatch could be causing the issue—just make sure both are using the same protocol and also dont forget to keep an eye on the backend logs!
Do get back to me if the issue persists.
 
Is that your full backend code? If there's more, could you share it, making sure to remove any sensitive data like API keys.

Sure, Here is the full backend minus all the secret stuff

JavaScript:
const express = require("express");
const multer = require("multer");
const { google } = require("googleapis");
const path = require("path");
const cors = require("cors");  // Importing cors package

// Initialize the Express app
const app = express();
const PORT = 3000;

// Use CORS middleware to allow requests from different origins
app.use(cors());

// Load service account credentials
const credentials = require("***************");
const auth = new google.auth.JWT(
  credentials.client_email,
  null,
  credentials.private_key,
  ["******************"]
);
const drive = google.drive({ version: "v3", auth });

// Set up multer for file uploads
const upload = multer({
  dest: 'uploads/',
  limits: { fileSize: 10000000 } // 10MB limit, adjust as necessary
});

// Add the /upload route
const fs = require("fs").promises; // Use promises for cleaner async handling

app.post("/upload", upload.single("file"), async (req, res) => {
  console.log('Received file:', req.file); // Debug: Check file info
  if (!req.file) {
      return res.status(400).json({ message: 'No file uploaded' });
  }
  try {
      console.log('File received:', req.file); // Debugging: Ensure the file is received
      const filePath = path.join(__dirname, req.file.path); // Get the correct path to the uploaded file

      const fileMetadata = {
          name: req.file.originalname,
          parents: ["*******************"], // Replace with your folder ID
      };
      const media = {
          mimeType: req.file.mimetype,
          body: require("fs").createReadStream(filePath),
      };

      // Upload file to Google Drive
      const response = await drive.files.create({
          resource: fileMetadata,
          media: media,
          fields: "id",
      });

      console.log('File uploaded to Drive:', response.data.id); // Debugging: Ensure upload was successful

      // Attempt to delete the file from the server's 'uploads' folder
      try {
          console.log('Deleting file at:', filePath);
          await fs.unlink(filePath); // Use promises for cleaner async handling
          console.log('File deleted successfully.');
      } catch (err) {
          console.error("Error deleting temp file:", err); // Log error if file deletion fails
      }
// Respond with the file ID
const responseData = { fileId: response.data.id };
console.log('Response to be sent:', responseData); // Log the response data
      res.status(200).json({ fileId: response.data.id }); // Respond with the file ID
  } catch (error) {
      console.error('Error during file upload:', error);
      res.status(500).json({ message: 'Failed to upload file.', error: error.message });
  }
});


// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
 
Hey there!
The "Failed to fetch" error usually means there’s an issue with your frontend talking to the backend. First, double-check that your backend is running at http://localhost:3000/upload and that it’s accessible. If it’s all good, the problem could be a CORS issue—browsers block requests between different origins sometimes, so adding CORS support in your backend might help. Just throw in something like this:
JavaScript:
const cors = require('cors');
app.use(cors());
Another thing to check is the blob URL (playback.src). Make sure it’s valid and hasn’t expired before you try fetching it. Also, if your frontend is on https:// and your backend is on http://, that mismatch could be causing the issue—just make sure both are using the same protocol and also dont forget to keep an eye on the backend logs!
Do get back to me if the issue persists.
Hey,

Thanks for the reply, i've got CORS support and the file is being uploaded to google drive so i the blob URL can't be expiring. I also just checked and both frontend and backend are on http:// (i was really hoping that this was the issue). Backend logs all look good, i get entrys for receiving the blob, uploading and file deletion from the temp folder.

Only other thing to note is in browser devtools, it says the upload is cancelled. However, i'm 100% receiving the uploaded file in google drive. Screenshot 2024-11-28 074401.png
 

Buy us a coffee!

Buy me a coffee.
Back
Top Bottom