You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure部署BotFramework时从Buffer写文件遇InternalServerError问题

Fixing ENOENT Error When Saving Receipt Attachments to Azure App Service

Hey there, let's break down why your receipt bot is throwing that ENOENT error on Azure and how to fix it quickly.

The Root Cause

Your local development environment lets you write files directly to your project's wwwroot directory because you have full filesystem permissions there. But Azure App Service sets the D:\home\site\wwwroot directory as read-only by default—so any attempt to write files there will fail with a "no such file or directory" error, even if the path looks correct.

Additionally, your current code uses the asynchronous fs.writeFile without waiting for it to complete, which could lead to race conditions, but the main culprit here is the read-only filesystem restriction.

Solutions

We have two solid options here—one for temporary testing, and one for production-ready persistent storage.

Option 1: Use Azure's Temporary Storage (Quick Testing Fix)

Azure provides a writable temporary directory at D:\local\Temp (you can also access it via the TEMP environment variable). This works for quick tests, but note that all files here will be deleted when your app restarts or scales.

Update your path logic to use this directory, and switch to the promise-based file write to ensure completion:

// Update the path to use temporary storage
const localFileName = path.join(process.env.TEMP || 'D:\\local\\Temp', attachment.name);

// Replace fs.writeFile with promise-based version to wait for completion
await fs.promises.writeFile(localFileName, response.data);

Option 2: Use Azure Blob Storage (Production-Grade)

For a persistent solution (since you need to keep receipts to submit to your accounting API), Azure Blob Storage is the right choice—it's designed for storing unstructured data like images and integrates seamlessly with App Service.

  1. Install the Azure Storage SDK:
npm install @azure/storage-blob
  1. Update your handleReceipts function to use Blob Storage instead of local files:
const { BlobServiceClient } = require('@azure/storage-blob');
const path = require('path');
const axios = require('axios');

async function handleReceipts(attachments) {
  const attachment = attachments[0];
  const url = attachment.contentUrl;
  const blobName = attachment.name;

  // Get your storage connection string from Azure Portal (add to App Service env vars)
  const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING);
  const containerClient = blobServiceClient.getContainerClient('receipts'); // Ensure this container exists in your storage account

  try {
    const response = await axios.get(url, { responseType: 'arraybuffer' });
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    
    // Upload receipt to Blob Storage with correct content type
    await blockBlobClient.upload(response.data, response.data.length, {
      blobHTTPHeaders: { blobContentType: attachment.contentType }
    });

    return `Successfully saved receipt: ${blobName}`;
  } catch (error) {
    console.error('Error saving receipt:', error);
    return undefined;
  }
}
  1. Configure your storage connection string:
  • Create an Azure Storage account and a container named receipts (set appropriate access levels).
  • In the Azure Portal, go to your App Service → Configuration → Application Settings, add a new setting named AZURE_STORAGE_CONNECTION_STRING with your storage account's connection string.

Quick Verification Checks

  • Confirm your Azure App Service can access Blob Storage via the connection string (no extra permissions needed if using the full connection string).
  • If using temporary storage, log the localFileName to ensure it points to D:\local\Temp instead of wwwroot.

内容的提问来源于stack exchange,提问作者Hessel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:48:32