拋棄trycatch,用go的思想去處理js異常

語言: CN / TW / HK

theme: github

errors

錯誤處理在編程中是不可避免的一部分,在程序開發過程中,不可必要的會出現各種的錯誤,是人為也可能是失誤,任何不可預料的可能都會發生

為了更好的保證程序的健壯性和穩定性

我們必須要對錯誤處理有更好的認識

最近迷上了golang的錯誤處理哲學,希望由淺入深的總結一下自己的思考和看得見的思考

👀 用 error 表示可能出現的錯誤,用throw強制拋出錯誤

通常情況下 錯誤處理的方式無非不過兩種

  • 泛處理
  • 精處理

其實都很好理解

``` // 偽代碼

try { const file = await readFile('../file')

const content = filterContent(file)

} catch (e) { alert('xxxx',e.msg) } ```

泛處理指的是對所有可能的錯誤都使用相同的處理方式,比如在代碼中使用相同統一的錯誤提示信息

這種方式適用於一些簡單的,不太可能發生的錯誤,不如文件不存在,網絡連接超時等。

對於更加複雜的錯誤,應該使用精處理,即根據具體情況對不同類型的錯誤進行特定的處理

```

const [readErr,readFile] = await readFile('../file')

if (readErr) { // 處理讀取錯誤 return }

const [filterErr,filterContent] = filterContent(readFile)

if (filterErr) { // 處理過濾錯誤 return } ```

精處理可以讓我們把控計劃的每一步,問題也很顯然暴露了出來,過於麻煩

在實際開發當中,我們需要根據實際情況選擇適當的方式進行錯誤處理。

由於本人是精處理分子,基於此開發了一個js版本的errors

如何定義一個錯誤

``` import { Errors } from '@memo28/utils'

Errors.News('err') ```

如何給一個錯誤分類

``` import { Errors } from '@memo28/utils'

Errors.News('err', { classify: 1 }) ```

如何判斷兩個錯誤是相同類型

``` import { Errors } from '@memo28/utils'

Errors.As(Errors.News('err', { classify: 1 }), Errors.News('err2', { classify: 1 })) // true

Errors.As(Errors.News('err', { classify: 1 }), Errors.News('err2', { classify: 2 })) // false ```

一個錯誤包含了哪些信息?

``` Errors.New('as').info() // { msg: 'as' , classify: undefined }

Errors.New('as').trace() // 打印調用棧

Errors.New('as').unWrap() // 'as' ```

最佳實踐

```ts import { AnomalousChain, panicProcessing } from '@memo28/utils'

class A extends AnomalousChain { // 定義錯誤處理函數, // 當每次執行的被 panicProcessing 裝飾器包裝過的函數都會檢查 是否存在 this.errors 是否為 ErrorsNewResult 類型 // 如果為 ErrorsNewResult 類型則 調用 panicProcessing的onError回調 和 skip函數 skip(errors: ErrorsNewResult | null): this { console.log(errors?.info().msg) return this }

@panicProcessing() addOne(): this { console.log('run one') super.setErrors(Errors.New('run one errors')) return this }

@panicProcessing({ // 在 skip 前執行 onError(error) { console.log(error.unWrap()) }, // onRecover 從錯誤中恢復, 當返回的是true時 繼續執行addTwo內邏輯,反之 // onRecover(erros) { // return true // }, }) addTwo(): this { console.log('run two') return this } } new A().addOne().addTwo()

// output run one run one errors // in onError run one errors // in skip fn

```