2017-10-17 62 views
0

考慮以下(僞)函數來更新數據庫:處理/捕獲錯誤,無需重複代碼?

function my_function(req, res, input) { 
    try { 
    // This sanitizeInput() function throws error message if input is invalid 
    sanitizeInput(input); 
    catch (err) { 
    res.status(500).json({id:"sql_error",message:err}); 
    return; 
    } 

    dbCreateRowPromise(input) 
    .then(result => {//Handle success}) 
    .catch(err => {res.status(500).json({id:"sql_error",message:err}}) 
} 

正如你可以看到我書面方式抓兩次,兩次我寫相同的響應500的地位,並在同一處理漁獲辦法。有沒有什麼好的方法可以將這兩個漁獲結合在一起?

+0

這些類型的問題不提供** **問題。這屬於[代碼評論](https://codereview.stackexchange.com/)。 – ProEvilz

+0

@ProEvilz我不這麼認爲,代碼審查需要運行代碼,僞代碼並不真的讓他們感興趣。 – Icepickle

+0

@Ippickle這個問題是'我該如何改進我的代碼'的問題。不要緊,無論是在這種情況下,因爲僞高亮部分是使用捕捉的&try塊。 – ProEvilz

回答

1

注意,在當前的編寫代碼的方式,你不返回任何東西,任何下列語句將假定一切正常,因爲您正在處理catch,並轉換響應。

我想你可以只重寫你的聲明以下列方式:

function sanitizeInput(input) { 
 
    if (input % 2 === 0) { 
 
    throw 'Cannot input even number'; 
 
    } 
 
    return input; 
 
} 
 

 
function dbCreateRowPromise(input) { 
 
    return Promise.resolve(input); 
 
} 
 

 
function my_function(input) { 
 
    return Promise.resolve(input) 
 
    .then(sanitizeInput) 
 
    .then(dbCreateRowPromise); 
 
} 
 

 
// perfectly normall input 
 
my_function(5) 
 
    .then(out => console.log(out)) 
 
    .catch(err => console.log('error occured', err)); 
 
    
 
// errourness input 
 
my_function(4) 
 
    .then(out => console.log(out)) 
 
    .catch(err => console.log('error occured', err));

只需使用承諾修建一連串的事件,並讓錯誤被拋出。如果不是被調用者處理的,最終會在控制檯中顯示錯誤。

+0

我首先選擇了不同的答案被接受的一個,但最終好幾次看着這個答案,因爲它提供的工作代碼,所以決定改變公認的答案因爲它對我來說是最有用的。謝謝=) –

0

最簡單的方法是使用async/await語法你的函數:

async function my_function(req, res, input) { 
    try { 
    input = sanitizeInput(input); 
    let result = await dbCreateRowPromise(input); 
    // handle result 
    } catch (err) { 
    res.status(500).json({id:"sql_error",message:err}); 
    } 
} 

或者,作出承諾爲sanitizeInput,這樣就可以使用承諾鏈接和處理來自它的錯誤的拒絕。

var promise; 
try { 
    promise = Promise.resolve(sanitizeInput(input)); 
} catch (err) { 
    promise = Promise.reject(err); 
} 
promise.then(input => 
    dbCreateRowPromise(input) 
).then(result => { 
    // Handle success 
}).catch(err => { 
    res.status(500).json({id:"sql_error",message:err}); 
}); 

new Promise(resolve => 
    resolve(sanitizeInput(input)) 
).then(input => 
    dbCreateRowPromise(input) 
).then(…).catch(…); 

Promise.resolve(input).then(sanitizeInput).then(dbCreateRowPromise).then(…).catch(…) 
1

看起來你所遇到的是同步代碼,承諾和異步回調的混合體,它們具有不同的錯誤處理技術。

一個解決方案是隻做你正在做的事情,單獨處理不同類型的錯誤,但這會變得混亂和複雜。另一種是試圖將所有這些代碼統一成一種風格,使用簡單的抽象來平滑它們。

我會親自嘗試將所有呼叫標準化爲異步回調樣式調用,然後統一錯誤處理方式。例如,它看起來像是在這裏使用express中間件,所以我會將所有錯誤傳出並在錯誤處理中間件中處理它們。

import { auto, constant } from 'async' 
const { assign } from Object 

function sanitize (opts, callback) { 
    const { input } = opts 
    try { 
    sanitizeInput(input) 
    callback() 
    } catch (err) { 
    callback(assign(err, { status: 'sanitize_error', statusCode: 500 }) 
    } 
} 

function createRow (opts, callback) { 
    const { santizie: input } = opts 
    dbCreateRowPromise(input) 
    .then(result => callback(null, result)) 
    .catch(err => callback(assign(err, { status: 'create_row_error', statusCode: 500 })) 
} 

function my_function(req, res, input, next) { 
    const block = { 
    input: constant(input), 
    sanitize: ['input', sanitize], 
    createRow: ['sanitize', createRow] 
    } 

    auto(block, (err, result) => { 
    if (err) return next(err) 
    res.status(200).json({ status: 'ok' })) 
    }) 
} 

function errorHandler(err, req, res) { 
    res.status(err.statusCode).json(err) 
} 
+0

我看不出有任何異步回調在OPS代碼。你爲什麼從承諾回到nodeback風格? – Bergi

+0

我也沒有,但在包裝功能部件'函數創建my_function(REQ,RES輸入)'看起來這確實居然有一個可選的暗示回調明確的功能。在開始使用回調之前,您還沒有深入瞭解Express。因此,它可能不是在這個問題明確的,但我推斷,這是更廣泛的答案的一部分。 –

+0

我一直包裹快遞,使其與承諾,恢復路由器的處理程序正常工作:-) – Bergi

1

你應該考慮讓sanitizeInput返回一個承諾。然後,你可以這樣寫:

sanitizeInput(input) 
.then(function(data)){ 
    return dbCreateRowPromise(input); 
}) 
.then(function(data)){ 
    //success 
}) 
.catch(function(error)){ 
    //all failures 
}) 

我假設你的函數返回的東西 - 如果不是data也只是空