[英]Using throw in a Javascript expression
這是我想要做的:
var setting = process.env.SETTING || throw new Error("please set the SETTING environmental variable");
^^^^^
但是解釋器抱怨“語法錯誤:意外的令牌拋出”。
有沒有辦法在我們比較一個值是否為假的同一行中拋出異常?
您可以利用 javascript 的功能特性:
var setting = process.env.SETTING ||
function(){
throw "please set the SETTING environmental variable";
}();
// es201x
var setting = process.env.SETTING ||
(() => {throw `SETTING environmental variable not set`})();
或更通用的創建一個函數來拋出錯誤並使用它:
function throwErr(mssg){
throw new Error(mssg);
}
var setting = process.env.SETTING ||
throwErr("please set the SETTING environmental variable");
我使用的一個片段:
const throwIf = ( assertion = false, message = `An error occurred`, ErrorType = Error) => assertion && (() => { throw new ErrorType(message); })(); throwIf(!window.SOMESETTING, `window.SOMESETTING not defined`, TypeError);
throw
是一個語句,而不是一個表達式,因此您不能將它用作另一個表達式的一部分。 你必須拆分它:
var setting = process.env.SETTING;
if (!setting) throw new Error("please set the SETTING environmental variable");
有一個草案提案將 throw 表達式(類似於 C# 7 的throw 表達式)引入 JavaScript/ECMAScript:
用大括號把它包起來
{throw ...}
或者用一個函數包裹它(女巫實際上將它包裹在大括號內)
()=>{throw ..}
//or:
function(){throw..}
我看到你在使用 nodejs。
我認為驗證輸入參數的最佳方法是斷言。 NodeJS 內置了簡單的斷言模塊: http : //nodejs.org/api/assert.html
並使用它,例如,像這樣:
var assert = require('assert');
// ...
function myFunction (param) {
assert(param, 'please pass param');
// ...
}
對於測試環境,您可以這樣做:
require('assert')(process.env.setting, 'please set the SETTING environmental variable');
或者:
;(function (a) {
a(process.env.setting, 'please set the SETTING environmental variable');
a(process.env.port, 'please set the PORT environmental variable');
}(require('assert')));
不是問題的直接答案,但如果您使用的是 TypeScript,我發現runtypes是手動驗證和拋出的絕佳替代方案。 當輸入類型為output | null | undefined
時,OP 中的方法有效output | null | undefined
output | null | undefined
output | null | undefined
或類似的東西,runtypes 也可以在輸入類型為any
,例如在防御性解碼具有已知結構的 JSON 時。
你會像這樣使用它:
import { String } from 'runtypes';
const setting = String.check(process.env.SETTING)
如果process.env.SETTING
是undefined
它會拋出。 添加.withConstraint()
以添加其他條件。 該庫實際上非常強大,不僅可以驗證簡單類型,還可以以類型安全的方式驗證記錄(接口)、聯合等。
一個缺點是您無法自定義錯誤消息(“失敗的約束檢查”),這在許多快速而骯臟的情況下是可以的,因為發生錯誤的行會告訴您問題是什么。
io-ts是另一個類似的庫,盡管它似乎有一種更復雜的方法,並且目前還在不斷變化。
throw
沒有返回值。 所以你不能那樣使用它。 但是,您可以將 throw 包裝在函數中。 到時候就可以了。 但是找到異常的來源會更困難。
const getenv = require('getenv');
const setting = getenv('SETTING');
如果 SETTING 不存在,您將獲得:
… getenv.js:14
throw new Error('GetEnv.Nonexistent: ' + varName + ' does not exist ' +
^ Error: GetEnv.Nonexistent: SETTING does not exist and no fallback value provided.
順便說一句,我的經驗告訴我,環境變量的默認值是邪惡的。
雖然不能直接將throw
用作表達式,但它可以像Koooilnc建議的那樣在立即調用的匿名閉包中使用,或者像casablanca建議的那樣分離到它自己的語句中,或者像Alex Yarochevich建議的那樣用 Node 的assert
替換。
然而,今天執行此操作的最常見和慣用的方法可能是使用tiny-invariant
或類似的 function。
invariant(process.env.SETTING, "SETTING environment variable is required");
const setting = process.env.SETTING;
或者
const setting = process.env.SETTING;
invariant(setting, "SETTING environment variable is required");
它比立即調用的匿名閉包更簡單,比單獨的 if-throw 語句更清晰和更短(因為條件未反轉),並且與 Node 的assert
不同,TypeScript 中的類型適當縮小,可以在瀏覽器中使用。
它也比我之前建議的使用運行時類型庫輕量得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.