iT邦幫忙

2022 iThome 鐵人賽

DAY 22
2

Errors

Moleculer 內建了一些 Error 可以用來在服務中拋出錯誤。

基本錯誤類別

MoleculerError

MoleculerError 是基本的錯誤類別。

名稱 類型 預設值 說明
message String 錯誤訊息
code Number 500 錯誤碼
type String 錯誤類型
data any 任何相關資料

範例:

const { MoleculerError } = require("moleculer").Errors;

throw new MoleculerError(
    "Something happened",
    501,
    "ERR_SOMETHING",
    { a: 5, nodeID: "node-666" }
);

MoleculerRetryableError

MoleculerRetryableError 是可重試的錯誤。它被用於 broker.call ,如果 Broker 被駁回但拿到 MoleculerRetryableError 的話它將會重試。

名稱 類型 預設值 說明
message String 錯誤訊息
code Number 500 錯誤碼
type String 錯誤類型
data any 任何相關資料
const { MoleculerRetryableError } = require("moleculer").Errors;

throw new MoleculerRetryableError(
    "Some retryable thing happened",
    501,
    "ERR_SOMETHING",
    { a: 5, nodeID: "node-666" }
);

MoleculerServerError

MoleculerServerError 是一個可重試的服務錯誤。它的參數與 MoleculerRetryableError 相同。

MoleculerClientError

MoleculerClientError 是一個 無法 重試的客戶端錯誤。它的參數與 MoleculerError 相同。

內部錯誤類別

ServiceNotFoundError

拋出情境:如果你呼叫了一個尚未註冊的服務 Action 。
錯誤碼:404
可重試:true
類型:SERVICE_NOT_FOUND

ServiceNotAvailableError

拋出情境:如果你呼叫了一個當前不可用的服務 Action。例如節點服務斷線或是斷路器跳閘。
錯誤碼:404
可重試:true
類型:SERVICE_NOT_AVAILABLE

RequestTimeoutError

拋出情境:如果請求逾時。
錯誤碼:504
可重試:true
類型:REQUEST_TIMEOUT

RequestSkippedError

拋出情境:如果使用巢狀呼叫時,當前面的呼叫逾時了,下一個巢狀呼叫將會拋出這個錯誤。
錯誤碼:514
可重試:false
類型:REQUEST_SKIPPED

RequestRejectedError

拋出情境:如果被呼叫的節點在請求過程中發生斷線。
錯誤碼:503
可重試:true
類型:REQUEST_REJECTED

QueueIsFullError

拋出情境:如果有太多請求導致隊列滿載。
錯誤碼:429
可重試:true
類型:QUEUE_FULL

ValidationError

拋出情境:如果呼叫的參數驗證無效。
錯誤碼:422
可重試:false
類型:VALIDATION_ERROR (default)

MaxCallLevelError

拋出情境:如果巢狀呼叫達到最大層數 (避免無窮迴圈)。
錯誤碼:500
可重試:false
類型:MAX_CALL_LEVEL

ServiceSchemaError

拋出情境:如果你的服務綱目無效
錯誤碼:500
可重試:false
類型:SERVICE_SCHEMA_ERROR

BrokerOptionsError

拋出情境:如果你的 Broker 選項無效。
錯誤碼:500
可重試:false
類型:BROKER_OPTIONS_ERROR

GracefulStopTimeoutError

拋出情境:當優雅的關閉卻逾時
錯誤碼:500
可重試:false
類型:GRACEFUL_STOP_TIMEOUT

ProtocolVersionMismatchError

拋出情境:當舊版節點 ID 以過時的協定連線時
錯誤碼:500
可重試:false
類型:PROTOCOL_VERSION_MISMATCH

InvalidPacketDataError

拋出情境:當 Transporter 收到無效的資料時
錯誤碼:500
可重試:false
類型:INVALID_PACKET_DATA

建立客製化錯誤

你可以透過繼承 MoleculerError 來建立客製化的 Error 類別。

const { MoleculerError } = require("moleculer").Errors;

class MyBusinessError extends MoleculerError {
    constructor(msg, data) {
        super(msg || `This is my business error.`, 500, "MY_BUSINESS_ERROR", data);
    }
}

遠端傳輸保留客製化錯誤

你可以客製化 Regenerator 提供遠端節點傳輸時,還原客製化的錯誤類別。官方建議可以參考 Errors.Regenerator[2] 的原始碼來修改,再實作 restoreextractPlainErrorrestoreCustomError 方法。

方法 返回 說明
restore(plainError, payload) Error 還原錯誤物件
extractPlainError(err) Object 從錯誤物件取得一般錯誤物件
restoreCustomError(plainError, payload) Errorundefined Hook 還原子類別中的客製化錯誤。

範例:建立客製化 regenerator。例如建立一個 TimestampedError 的客製化錯誤類別,再建立一個 CustomRegenerator 類別來做還原處理。

custom-regenerator.js

const { Regenerator, MoleculerError } = require("moleculer").Errors;
const { ServiceBroker } = require("moleculer");

class TimestampedError extends MoleculerError {
    constructor(message, code, type, data, timestamp) {
        super(message, code, type, data);
        this.timestamp = timestamp;
    }
}

class CustomRegenerator extends Regenerator {
    restoreCustomError(plainError, payload) {
        const { name, message, code, type, data, timestamp } = plainError;
        switch (name) {
            case "TimestampedError":
                return new TimestampedError(message, code, type, data, timestamp);
        }
    }

    extractPlainError(err) {
        return {
            ...super.extractPlainError(err),
            timestamp: err.timestamp
        };
    }
}

module.exports = CustomRegenerator;

範例:使用客製化 regenerator

moleculer.config.js

const CustomRegenerator = require("./custom-regenerator");

module.exports = {
    errorRegenerator: new CustomRegenerator()
}

參考文獻

[1] Errors, https://moleculer.services/docs/0.14/errors.html
[2] Errors Regenerator, https://github.com/moleculerjs/moleculer/blob/master/src/errors.js

家家酒小劇場

  • Otter - 我的程式就像我的人生充滿錯誤QAQ
  • Boxy - 程式開發就像人生多少都會遇到錯誤,你也無法預測錯誤從哪裡來,但可以使用錯誤類別來統一處理錯誤,它將會在開發上會給你帶來許多好處。

上一篇
Day 21 : Tracing
下一篇
Day 23 : Moleculer Runner
系列文
Moleculer 家家酒31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言