输送一段3.8.x异常捕获并弹框展示的代码,不用谢

if (DEBUG) {

    let _maxReportCount = 1;

    let _errorFunc = console.error.bind(console);

    console.error = (function (location, message, stack) {

        console.log("ShowError --- catch now", location);

        director.getScheduler().unscheduleAll();

        //director.getScheduler().pauseAllTargets();

        let msg = "";

        if (location.error) {

            msg = location.error.message + location.error.stack;

        }

        else {

            msg = location + message + stack;

        }

        if (_maxReportCount > 0) {

            setTimeout(() => {

                createErrorDialog(msg, () => {

                    _maxReportCount = 1;

                }, () => {

                    _maxReportCount = 1;

                });

            }, 500);

            _maxReportCount--;

        }

        else {

        }

    });

}


function createSpriteFrame(size: Size, color: Color): SpriteFrame {

    const height = size.height;

    const width = size.width;

    const colors = color;

    const data: Uint8Array = new Uint8Array(height * width * 4);

    for (let i = 0; i < data.byteLength / 4; ++i) {

        data[i * 4 + 0] = colors.r;

        data[i * 4 + 1] = colors.g;

        data[i * 4 + 2] = colors.b;

        data[i * 4 + 3] = colors.a;

    }

    const image: ImageAsset = new ImageAsset();

    image.reset({

        _data: data,

        _compressed: false,

        width: width,

        height: height,

        format: Texture2D.PixelFormat.RGBA8888

    });

    const texture: Texture2D = new Texture2D();

    texture.image = image;

    const spriteFrame: SpriteFrame = new SpriteFrame();

    spriteFrame.texture = texture;

    spriteFrame.packable = false;

    return spriteFrame;

}

function createErrorDialog(txt, onConfirm?: () => void, onCancel?: Function): Node {

    let dialog = new Node("ErrorDialog");

    let dialogTransform = dialog.addComponent(UITransform);

    let winSize = view.getVisibleSize();

    let dialogSize = size(winSize.width, winSize.height);

    dialogTransform.contentSize = dialogSize;

    dialog.setPosition(v3(0, 0));

    dialog.addComponent(BlockInputEvents);

    let bg = new Node("Background");

    let bgTransform = bg.addComponent(UITransform);

    bgTransform.contentSize = dialogSize;

    let bgSprite = bg.addComponent(Sprite);

    bgSprite.sizeMode = Sprite.SizeMode.CUSTOM;

    bgSprite.spriteFrame = createSpriteFrame(size(300, 200), new Color(255, 255, 255, 255));

    bg.parent = dialog;

    let content = new Node("content");

    let contentTransform = content.addComponent(UITransform);

    let contentLbComp = content.addComponent(Label);

    contentLbComp.string = txt;

    contentLbComp.overflow = Label.Overflow.CLAMP;

    contentLbComp.horizontalAlign = Label.HorizontalAlign.LEFT;

    contentLbComp.verticalAlign = Label.VerticalAlign.TOP;

    contentLbComp.enableWrapText = true;

    contentTransform.contentSize = size(winSize.width * 0.85, winSize.height * 0.7);

    contentLbComp.color = new Color(0, 0, 0, 255);

    contentLbComp.fontSize = 24;

    content.getComponent(UITransform).anchorPoint = v2(0.5, 0.5);

    content.position = v3(0, 0);

    content.parent = dialog;

    let confirmBtn = new Node("ConfirmBtn");

    let confirmBtnTransform = confirmBtn.addComponent(UITransform);

    confirmBtnTransform.contentSize = size(100, 40);

    let confirmBtnSprite = confirmBtn.addComponent(Sprite);

    confirmBtnSprite.spriteFrame = createSpriteFrame(size(100, 40), new Color(0, 255, 0, 255));

    let confirmBtnComp = confirmBtn.addComponent(Button);

    let confirmLabel = new Node("Label");

    let label = confirmLabel.addComponent(Label);

    label.string = "确定";

    label.horizontalAlign = Label.HorizontalAlign.CENTER;

    label.verticalAlign = Label.VerticalAlign.CENTER;

    confirmLabel.parent = confirmBtn;

    confirmBtn.position = v3(-150, -dialogSize.height / 2 + 50);

    confirmBtn.parent = dialog;

    let cancelBtn = new Node("CancelBtn");

    let cancelBtnTransform = cancelBtn.addComponent(UITransform);

    cancelBtnTransform.contentSize = size(100, 40);

    let cancelBtnSprite = cancelBtn.addComponent(Sprite);

    cancelBtnSprite.spriteFrame = createSpriteFrame(size(100, 40), new Color(128, 128, 128, 255));

    let cancelBtnComp = cancelBtn.addComponent(Button);

    let cancelLabel = new Node("Label");

    let cancelLabelComp = cancelLabel.addComponent(Label);

    cancelLabelComp.string = "取消";

    cancelLabelComp.horizontalAlign = Label.HorizontalAlign.CENTER;

    cancelLabelComp.verticalAlign = Label.VerticalAlign.CENTER;

    cancelLabel.parent = cancelBtn;

    cancelBtn.position = v3(150, -dialogSize.height / 2 + 50);

    cancelBtn.parent = dialog;

    cancelBtn.on(NodeEventType.TOUCH_END, () => {

        onCancel?.();

        dialog.destroy();

    });

    confirmBtn.on(NodeEventType.TOUCH_END, () => {

        onConfirm?.();

        dialog.destroy();

    });

    director.getScene().getChildByName("Canvas").addChild(dialog);

    return dialog;

}

要在原生端,展示你的报错,最重要的是要调用director.getScheduler().unscheduleAll()这个函数,
不然报错会无限刷新,导致你的UI框,没法展示。

2赞