Upload API with NextJS and Azure Portal not working?

Hello, I always get an error message when I upload videos via the API in the Azure Portal. Sometimes it looks like this:

 Parsed files: {  videoFile: [    PersistentFile {      _events: [Object: null prototype],      _eventsCount: 1,      _maxListeners: undefined,      lastModifiedDate: 2024-12-17T10:12:37.964Z,      filepath: 'C:\\Users\\thoma\\AppData\\Local\\Temp\\19612948a7cd7d81f78632e00.mp4',      newFilename: '19612948a7cd7d81f78632e00.mp4',      originalFilename: 'sample-2.mp4',      mimetype: 'video/mp4',      hashAlgorithm: false,      size: 30424618,      _writeStream: [WriteStream],      hash: null,      [Symbol(shapeMode)]: false,      [Symbol(kCapture)]: false    }  ] }

Sometimes (it seems to often work with smaller files) and the log looks like this:

 Uploading file from path: C:\Users\thoma\AppData\Local\Temp\19612948a7cd7d81f78632e00.mp4 Request timed out! File uploaded to Azure successfully: sample-2.mp4

Here I upload the API code:

 import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob'; import formidable from 'formidable'; import fs from 'fs/promises'; import { v4 as uuidv4 } from 'uuid'; export const config = {  api: {    bodyParser: false, // Disable default body parsing for file uploads  }, }; // Azure Storage connection string const AZURE_STORAGE_CONNECTION_STRING =  'DefaultEndpointsProtocol=https;AccountName=innowesovideos;AccountKey=uyJz3dlCW/hd+t3Y48pSfuk1Q+pV63S1Hs48uvGIJW3ubaO/ngtSMrzoKRvBE4so7MP9zz73uaLl+AStwmS6EA==;EndpointSuffix=core.windows.net'; export default async function handler(req, res) {  if (req.method !== 'POST') {    return res.status(405).json({ message: 'Only POST requests are allowed' });  }  let filePath = ''; // Variable to track the file path for cleanup  try {    // Set a timeout to prevent stalls    const timeout = setTimeout(() => {      console.error('Request timed out!');      if (!res.writableEnded) {        res.status(504).json({ message: 'Request timed out. Please try again.' });      }    }, 15000); // 15-second timeout    // Initialize formidable for file parsing    const form = formidable({      keepExtensions: true, // Keep file extensions      maxFileSize: 5000 * 1024 * 1024,    });    console.log('New filesize')    // Parse the incoming form data    const { files } = await new Promise((resolve, reject) => {      form.parse(req, (err, fields, files) => {        if (err) {          console.error('Error parsing form:', err);          reject(err);        } else {          resolve({ fields, files });        }      });    });    console.log('Parsed files:', files);    // Normalize videoFile input (handle single and multiple files)    const fileData = Array.isArray(files.videoFile) ? files.videoFile[0] : files.videoFile;    // Validate file presence and format    if (!fileData || !fileData.filepath) {      throw new Error('No video file provided.');    }    filePath = fileData.filepath;    if (!filePath) throw new Error('No valid file path found.');    if (fileData.mimetype !== 'video/mp4') throw new Error('Only MP4 files are allowed.');    console.log('Uploading file from path:', filePath);    // Generate a unique file name for Azure Blob Storage    const fileName = fileData.originalFilename || `${uuidv4()}.mp4`;    // Load the file as a buffer    const fileBuffer = await fs.readFile(filePath);    // Initialize Azure Blob Storage Client    const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);    const containerClient = blobServiceClient.getContainerClient('videos');    const blockBlobClient = containerClient.getBlockBlobClient(fileName);    // Upload the file to Azure Blob Storage    await blockBlobClient.uploadData(fileBuffer, {      blobHTTPHeaders: { blobContentType: 'video/mp4' },    });    // Generate a SAS token for the uploaded file    const sasToken = generateBlobSASQueryParameters(      {        containerName: 'videos',        blobName: fileName,        permissions: BlobSASPermissions.parse('r'), // Read permissions        startsOn: new Date(),        expiresOn: new Date(new Date().valueOf() + 3600 * 1000), // Token valid for 1 hour      },      blobServiceClient.credential    ).toString();    const videoUrl = `${blockBlobClient.url}?${sasToken}`;       clearTimeout(timeout);    return res.status(200).json({ message: 'Video uploaded successfully', videoUrl });  } catch (error) {    console.error('Error during upload:', error.message);    return res.status(500).json({ message: 'File upload failed', error: error.message });  } finally {       if (filePath) {      try {        await fs.unlink(filePath);        console.log(`Temporary file deleted: ${filePath}`);      } catch (cleanupErr) {        console.error(`Failed to delete temporary file: ${filePath}`, cleanupErr);      }    }  } }

Thanks!

(3 votes)
Loading...

Similar Posts

Subscribe
Notify of
3 Answers
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
regex9
3 months ago

I cannot read out any real error behavior from your information yet.

This issue:

Parsed files: {

comes from your console output here:

console.log('Parsed files:', files);

and the timeout is explicitly covered by your script.

const timeout = setTimeout(() => {
  console.error('Request timed out!');

With larger files it is not surprising. Maybe you just set the timeout higher. For example, at 2-5 minutes instead of only 15 seconds.

However, I do not see any indication that the upload had failed. expenditure

Uploading file from path: C:\Users\thoma\AppData\Local\Temp\19612948a7cd7d81f78632e00.mp4

File uploaded to Azure successfully: sample-2.mp4

indicate a successful upload.

regex9
3 months ago
Reply to  Thoss

The object you use as a second argument uploaddata can pass a callback (onProgress) record. The Event– Object you receive contains the already loaded bytes.