Merge pull request #778 from nonameShijian/PR-Branch

获取关于promise的错误堆栈
This commit is contained in:
Spmario233 2024-01-12 12:37:50 +08:00 committed by GitHub
commit bce8b75b05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 124 additions and 20 deletions

View File

@ -31,6 +31,7 @@ declare type GameEvent = import('../../noname/library/index.js').GameEvent;
declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise; declare type GameEventPromise = import('../../noname/library/index.js').GameEventPromise;
declare type Player = import('../../noname/library/index.js').Player; declare type Player = import('../../noname/library/index.js').Player;
declare type VCard = import('../../noname/library/index.js').VCard; declare type VCard = import('../../noname/library/index.js').VCard;
declare type Control = import('../../noname/library/index.js').Control;
declare type Video = import('../../noname/game/index.js').Video; declare type Video = import('../../noname/game/index.js').Video;
declare type Videos = import('../../noname/game/index.js').Videos; declare type Videos = import('../../noname/game/index.js').Videos;

View File

@ -752,10 +752,30 @@ function setServerIndex() {
} }
function setWindowListener() { function setWindowListener() {
// 但愿有用 /**
window.addEventListener("unhandledrejection", (error) => { * @type { [Error, NodeJS.CallSite[]][] }
// 希望error.reason能是个正常的error */
throw error.reason; const errorList = [];
// 这他娘的能捕获浏览器控制台里的输入值,尽量别用
// 在火狐里无效
Error.prepareStackTrace = function (e, stackTraces) {
errorList.push([e, stackTraces]);
};
// 已经有用了
window.addEventListener("unhandledrejection", promiseRejectionEvent => {
promiseRejectionEvent.promise.catch(e => {
const result = errorList.find(v => v[0] === e);
if (result) {
// @ts-ignore
window.onerror(
result[0].message,
result[1][0].getScriptNameOrSourceURL() || void 0,
result[1][0].getLineNumber() || void 0,
result[1][0].getColumnNumber() || void 0,
result[0]
);
}
});
}); });
window.onkeydown = function (e) { window.onkeydown = function (e) {
@ -857,6 +877,7 @@ function setWindowListener() {
}; };
window.onerror = function (msg, src, line, column, err) { window.onerror = function (msg, src, line, column, err) {
errorList.length = 0;
const winPath = window.__dirname ? ('file:///' + (__dirname.replace(new RegExp('\\\\', 'g'), '/') + '/')) : ''; const winPath = window.__dirname ? ('file:///' + (__dirname.replace(new RegExp('\\\\', 'g'), '/') + '/')) : '';
let str = `错误文件: ${typeof src == 'string' ? decodeURI(src).replace(lib.assetURL, '').replace(winPath, '') : '未知文件'}`; let str = `错误文件: ${typeof src == 'string' ? decodeURI(src).replace(lib.assetURL, '').replace(winPath, '') : '未知文件'}`;
str += `\n错误信息: ${msg}`; str += `\n错误信息: ${msg}`;

View File

@ -6,6 +6,23 @@ import { status as _status } from '../../status/index.js';
import { UI as ui } from '../../ui/index.js'; import { UI as ui } from '../../ui/index.js';
export class Dialog extends HTMLDivElement { export class Dialog extends HTMLDivElement {
/** @type { HTMLDivElement } */
contentContainer;
/** @type { HTMLDivElement } */
content;
/** @type { HTMLDivElement } */
bar1;
/** @type { HTMLDivElement } */
bar2;
/** @type { Button[] } */
buttons;
/** @type { boolean } */
static;
/** @type { boolean } */
noforcebutton;
/** @type { boolean } */
noopen;
// @ts-ignore // @ts-ignore
constructor(...args) { constructor(...args) {
if (args[0] instanceof Dialog) { if (args[0] instanceof Dialog) {
@ -18,7 +35,7 @@ export class Dialog extends HTMLDivElement {
let noTouchScroll = false; let noTouchScroll = false;
let forceButton = false; let forceButton = false;
let noForceButton = false; let noForceButton = false;
/** @type {this} */ /** @type { this } */
// @ts-ignore // @ts-ignore
const dialog = ui.create.div('.dialog'); const dialog = ui.create.div('.dialog');
Object.setPrototypeOf(dialog, Dialog.prototype); Object.setPrototypeOf(dialog, Dialog.prototype);
@ -40,6 +57,7 @@ export class Dialog extends HTMLDivElement {
if (!noTouchScroll) { if (!noTouchScroll) {
dialog.contentContainer.ontouchstart = ui.click.dialogtouchStart; dialog.contentContainer.ontouchstart = ui.click.dialogtouchStart;
dialog.contentContainer.ontouchmove = ui.click.touchScroll; dialog.contentContainer.ontouchmove = ui.click.touchScroll;
// @ts-ignore
dialog.contentContainer.style.webkitOverflowScrolling = 'touch'; dialog.contentContainer.style.webkitOverflowScrolling = 'touch';
dialog.ontouchstart = ui.click.dragtouchdialog; dialog.ontouchstart = ui.click.dragtouchdialog;
} }
@ -52,15 +70,21 @@ export class Dialog extends HTMLDivElement {
dialog._args = args; dialog._args = args;
return dialog; return dialog;
} }
/**
*
* @param { string | HTMLDivElement | Card[] | Player[] } item
* @param {*} [noclick]
* @param { boolean } [zoom]
*/
add(item, noclick, zoom) { add(item, noclick, zoom) {
if (typeof item == 'string') { if (typeof item == 'string') {
if (item.startsWith('###')) { if (item.startsWith('###')) {
var items = item.slice(3).split('###'); const items = item.slice(3).split('###');
this.add(items[0], noclick, zoom); this.add(items[0], noclick, zoom);
this.addText(items[1], items[1].length <= 20, zoom); this.addText(items[1], items[1].length <= 20, zoom);
} }
else if (noclick) { else if (noclick) {
var strstr = item; const strstr = item;
item = ui.create.div('', this.content); item = ui.create.div('', this.content);
item.innerHTML = strstr; item.innerHTML = strstr;
} }
@ -68,17 +92,23 @@ export class Dialog extends HTMLDivElement {
item = ui.create.caption(item, this.content); item = ui.create.caption(item, this.content);
} }
} }
// @ts-ignore
else if (['div', 'fragment'].includes(get.objtype(item))) { else if (['div', 'fragment'].includes(get.objtype(item))) {
// @ts-ignore
this.content.appendChild(item); this.content.appendChild(item);
} }
// @ts-ignore
else if (get.itemtype(item) == 'cards') { else if (get.itemtype(item) == 'cards') {
var buttons = ui.create.div('.buttons', this.content); const buttons = ui.create.div('.buttons', this.content);
if (zoom) buttons.classList.add('smallzoom'); if (zoom) buttons.classList.add('smallzoom');
// @ts-ignore
this.buttons = this.buttons.concat(ui.create.buttons(item, 'card', buttons, noclick)); this.buttons = this.buttons.concat(ui.create.buttons(item, 'card', buttons, noclick));
} }
// @ts-ignore
else if (get.itemtype(item) == 'players') { else if (get.itemtype(item) == 'players') {
var buttons = ui.create.div('.buttons', this.content); var buttons = ui.create.div('.buttons', this.content);
if (zoom) buttons.classList.add('smallzoom'); if (zoom) buttons.classList.add('smallzoom');
// @ts-ignore
this.buttons = this.buttons.concat(ui.create.buttons(item, 'player', buttons, noclick)); this.buttons = this.buttons.concat(ui.create.buttons(item, 'player', buttons, noclick));
} }
else if (item[1] == 'textbutton') { else if (item[1] == 'textbutton') {
@ -87,6 +117,7 @@ export class Dialog extends HTMLDivElement {
else { else {
var buttons = ui.create.div('.buttons', this.content); var buttons = ui.create.div('.buttons', this.content);
if (zoom) buttons.classList.add('smallzoom'); if (zoom) buttons.classList.add('smallzoom');
// @ts-ignore
this.buttons = this.buttons.concat(ui.create.buttons(item[0], item[1], buttons, noclick)); this.buttons = this.buttons.concat(ui.create.buttons(item[0], item[1], buttons, noclick));
} }
if (this.buttons.length) { if (this.buttons.length) {
@ -101,6 +132,10 @@ export class Dialog extends HTMLDivElement {
ui.update(); ui.update();
return item; return item;
} }
/**
* @param { string } str
* @param { boolean } [center]
*/
addText(str, center) { addText(str, center) {
if (str && str.startsWith('<div')) this.add(str); if (str && str.startsWith('<div')) this.add(str);
else if (center !== false) { else if (center !== false) {
@ -111,10 +146,12 @@ export class Dialog extends HTMLDivElement {
} }
return this; return this;
} }
addSmall(item, noclick) { addSmall(item, noclick) {
return this.add(item, noclick, true); return this.add(item, noclick, true);
} }
addAuto(content) { addAuto(content) {
// @ts-ignore
if (content && content.length > 4 && !this._hovercustomed) { if (content && content.length > 4 && !this._hovercustomed) {
this.addSmall(content); this.addSmall(content);
} }
@ -124,7 +161,7 @@ export class Dialog extends HTMLDivElement {
} }
open() { open() {
if (this.noopen) return; if (this.noopen) return;
for (var i = 0; i < ui.dialogs.length; i++) { for (let i = 0; i < ui.dialogs.length; i++) {
if (ui.dialogs[i] == this) { if (ui.dialogs[i] == this) {
this.show(); this.show();
this.refocus(); this.refocus();
@ -137,7 +174,7 @@ export class Dialog extends HTMLDivElement {
else ui.dialogs[i].hide(); else ui.dialogs[i].hide();
} }
ui.dialog = this; ui.dialog = this;
var translate; let translate;
if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains('fixed')) { if (lib.config.remember_dialog && lib.config.dialog_transform && !this.classList.contains('fixed')) {
translate = lib.config.dialog_transform; translate = lib.config.dialog_transform;
this._dragtransform = translate; this._dragtransform = translate;
@ -147,7 +184,7 @@ export class Dialog extends HTMLDivElement {
this.style.transform = 'scale(0.8)'; this.style.transform = 'scale(0.8)';
} }
this.style.transitionProperty = 'opacity,transform'; this.style.transitionProperty = 'opacity,transform';
this.style.opacity = 0; this.style.opacity = '0';
ui.arena.appendChild(this); ui.arena.appendChild(this);
ui.dialogs.unshift(this); ui.dialogs.unshift(this);
ui.update(); ui.update();
@ -158,10 +195,9 @@ export class Dialog extends HTMLDivElement {
else { else {
this.style.transform = 'scale(1)'; this.style.transform = 'scale(1)';
} }
this.style.opacity = 1; this.style.opacity = '1';
var that = this; setTimeout(() => {
setTimeout(function () { this.style.transitionProperty = '';
that.style.transitionProperty = '';
}, 500); }, 500);
return this; return this;
} }
@ -179,7 +215,12 @@ export class Dialog extends HTMLDivElement {
// } // }
return this; return this;
} }
/**
* @param { string } str
*/
setCaption(str) { setCaption(str) {
// @ts-ignore
this.querySelector('.caption').innerHTML = str; this.querySelector('.caption').innerHTML = str;
return this; return this;
} }

View File

@ -7,6 +7,7 @@
* @typedef { InstanceType<typeof lib.element.GameEvent> } GameEvent * @typedef { InstanceType<typeof lib.element.GameEvent> } GameEvent
* @typedef { InstanceType<typeof lib.element.GameEvent> & InstanceType<typeof lib.element.GameEventPromise> & typeof Promise<typeof lib.element.GameEvent> } GameEventPromise * @typedef { InstanceType<typeof lib.element.GameEvent> & InstanceType<typeof lib.element.GameEventPromise> & typeof Promise<typeof lib.element.GameEvent> } GameEventPromise
* @typedef { InstanceType<typeof lib.element.NodeWS> } NodeWS * @typedef { InstanceType<typeof lib.element.NodeWS> } NodeWS
* @typedef { InstanceType<typeof lib.element.Control> } Control
*/ */
import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction, characterDefaultPicturePath } from "../util/index.js"; import { nonameInitialized, assetURL, userAgent, Uninstantable, GeneratorFunction, AsyncFunction, characterDefaultPicturePath } from "../util/index.js";
import { AI as ai } from '../ai/index.js'; import { AI as ai } from '../ai/index.js';

View File

@ -14026,25 +14026,65 @@ export class UI extends Uninstantable {
static touchlines = []; static touchlines = [];
static todiscard = {}; static todiscard = {};
/** /**
* @type {HTMLStyleElement[]} * @type { HTMLStyleElement[] }
*/ */
static playerPositions = []; static playerPositions = [];
static create = Create; static create = Create;
static click = Click; static click = Click;
static selected = { static selected = {
/** /**
* @type { import('../library/index.js').Button[]} * @type { Button[] }
*/ */
buttons: [], buttons: [],
/** /**
* @type { import('../library/index.js').Card[]} * @type { Card[] }
*/ */
cards: [], cards: [],
/** /**
* @type { import('../library/index.js').Player[]} * @type { Player[] }
*/ */
targets: [] targets: []
} }
/**
* @type { Dialog[] }
*/
static dialogs;
/**
* @type { Dialog }
*/
static dialog;
/**
* @type { HTMLDivElement }
*/
static arena;
/**
* @type { Control[] }
*/
static controls;
/**
* @type { Control }
*/
static control;
/**
* @type { Control | undefined }
*/
static confirm;
/**
* @type { Control | undefined }
*/
static skills;
/**
* @type { Control | undefined }
*/
static skills1;
/**
* @type { Control | undefined }
*/
static skills2;
/**
* @type { Control | undefined }
*/
static skills3;
static refresh(node) { static refresh(node) {
void window.getComputedStyle(node, null).getPropertyValue("opacity"); void window.getComputedStyle(node, null).getPropertyValue("opacity");
} }