哈囉各位邦友們,這邊有一隻 API 是用來複製 Server 上 Shared Folder 的圖片
所以模組的部分有使用到 smb2
由於這個模組提供的皆是非同步的 function,沒有類似 fs.writeFileSync 的同步 function,所以用了 async/await 及 Promise 來達成同步
以下是複製圖片相關的 Code,圖片皆有大、中、小三張圖,複製完成後才會 send 訊息給前端去接收
function ReadPhotoFile(src) {
return new Promise(function (resolve, reject) {
smb2.readFile(src, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
})
}
function WritePhotoFile(dest, data) {
return new Promise(function(resolve, reject) {
smb2.writeFile(dest, data, function (err, callback) {
if (err) {
console.log('WRITE ERROR!')
reject(err);
} else {
resolve(callback);
}
});
})
}
async function CopyFile(src, dest) {
try {
let data = await ReadPhotoFile(src)
await WritePhotoFile(dest, data)
} catch (error) {
console.error(error);
}
}
// 實際執行的部分
async function() {
//...
await CopyFile(`${path}\\${Sketch_Month_s}\\Large\\${file_s}`, `${path}\\${Sketch_Month_d}\\Large\\${file_d}`);
await CopyFile(`${path}\\${Sketch_Month_s}\\${file_s}`, `${path}\\${Sketch_Month_d}\\${file_d}`);
await CopyFile(`${path}\\${Sketch_Month_s}\\Thumb\\${file_s}`, `${path}\\${Sketch_Month_d}\\Thumb\\${file_d}`);
await res.send("success");
}
WRITE ERROR!
{ Error: STATUS_PENDING (0x00000103) : The operation that was requested is pending completion.
at Object.<anonymous>(D:\***\***\node_modules\smb2\lib\tools\message.js:25:21)
at Socket.<anonymous> (D:\***\***\node_modules\smb2\lib\tools\smb2-forge.js:72:31)
at Socket.emit (events.js:189:13)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:265:11)
at Socket.Readable.push (_stream_readable.js:220:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17) code: 'STATUS_PENDING' }
這邊皆是複製大圖時會跳出此訊息!雖然大圖沒複製成功,但程式並不會 crash,中圖小圖皆能複製完成,並發送訊息給前端,但這個結果反而不是我們想要的
想請問這個錯誤到底是我們對於 async/await 及 Promise 的掌握度不夠?
又或者其實是 smb2 Source Code 造成的問題呢?
這個錯誤真的很困擾,煩請邦友們解答
從這篇文章可以看到一些SMB2/SMB3的資訊:
https://blogs.msdn.microsoft.com/openspecification/2013/03/27/smb-2-x-and-smb-3-0-timeouts-in-windows/
裡面提到怎樣會返回STATUS_PENDING,這不是失敗,而是系統通知client他要採用非同步的作業。
但是它程式處理返回的訊息是這樣寫:
https://github.com/bchelli/node-smb2/blob/master/lib/tools/message.js
var defaults = {
successCode: 'STATUS_SUCCESS'
, parse:function(connection, cb){
...
if(err.code == self.successCode){
...
} else {
...
}
...
結果就是非STATUS_SUCCESS
的話就會失敗。
如果知道怎麼改,建議你改了它原始碼送PR給作者。
所以你是想要全部 CopyFile 都沒問題
才 send message 到前端嗎
你原本的 code
用 await CopyFile
他的確有等他執行完
執行有錯誤也拿到錯誤
但是沒人跟他說有錯誤要停下來
他只會一直往下執行
我的理解啦