울면서개발하기
JAVA SCRIPT / NEXACRO

넥사크로 스크립트 오류를 화면에 토스트로 띄우기

· 2026년 10월 25일 다시 씀

넥사크로 HTML5 화면을 시험하다 보면 스크립트 오류가 콘솔에만 찍혀서 놓치기 쉽다. 아래 스크립트를 개발자도구 콘솔에 붙여 넣으면 넥사크로 트레이스 로그와 자바스크립트 오류가 화면 왼쪽 위에 토스트 메시지로 뜨고 잠시 뒤 사라진다(트레이스 로그 2초, 오류 5초). 넥사크로 14 와 24 에서 써 봤다.

스크립트

(function () {
  // 토스트 하나를 화면 왼쪽 위에 띄우고 delay(ms) 뒤에 지운다
  function showToast(message, delay) {
    var container = document.getElementById("nx-debug-toast");
    if (!container) {
      container = document.createElement("div");
      container.id = "nx-debug-toast";
      Object.assign(container.style, {
        position: "fixed", top: "50px", left: "0px",
        display: "flex", flexDirection: "column", alignItems: "flex-start",
        gap: "10px", pointerEvents: "none", zIndex: "2147483647"
      });
      document.body.appendChild(container);
    }

    var box = document.createElement("div");
    box.innerText = message;
    Object.assign(box.style, {
      pointerEvents: "auto", whiteSpace: "nowrap", padding: "5px 10px",
      background: "white", border: "3px solid #ffb3ba", borderRadius: "10px",
      boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
      transition: "opacity 0.5s ease, transform 0.5s ease"
    });
    container.appendChild(box);

    setTimeout(function () {
      box.style.opacity = "0";
      box.style.transform = "translateX(-50px)";
      setTimeout(function () {
        box.remove();
        if (!container.childNodes.length) container.remove();
      }, 500);
    }, delay || 2000);
  }

  // 1) 넥사크로 트레이스 로그: 원래 함수는 그대로 실행하고 토스트만 덧붙인다
  var originalTrace = nexacro._writeTraceLog;
  nexacro._writeTraceLog = function (level, msg, isSystem) {
    var ret = originalTrace.apply(this, arguments);
    var levelChar = ["F", "E", "W", "I"][level] || "D";
    showToast((isSystem === true ? "S" : "U") + levelChar + " " + msg);
    return ret;
  };

  // 2) 잡히지 않은 자바스크립트 오류
  window.addEventListener("error", function (e) {
    var text = "오류: " + e.message + "\n위치: " + e.filename +
               "\n줄: " + e.lineno + " (칸: " + e.colno + ")";
    if (e.error && e.error.stack) text += "\n\n" + e.error.stack;
    showToast(text, 5000);
  });

  // 3) 처리하지 않은 Promise 거부
  window.addEventListener("unhandledrejection", function (e) {
    var r = e.reason;
    showToast("비동기 오류: " + (r ? (r.message || r) : "알 수 없는 오류"), 5000);
  });
})();

화면에는 이런 식으로 나온다.

UW 12:20:26:120 [WARN] [Layout] callCommand mainframe....form.div_work focus failure

앞의 두 글자는 원래 넥사크로 트레이스 로그 형식을 따른 것이다. 첫 글자는 시스템(S)/사용자(U), 두 번째 글자는 수준(F 치명, E 오류, W 경고, I 정보, D 디버그)이다.

쓸 때 알아 둘 것

  • nexacro._writeTraceLog 는 이름이 _ 로 시작하는 내부 함수다. 공식 API 가 아니라서 인자 순서나 이름이 버전마다 달라질 수 있다. 개발 PC 에서 디버깅할 때만 쓰고 운영 코드에는 넣지 않는다
  • 원래 함수를 통째로 바꾸지 않고 감싸서(apply) 부르기 때문에, 콘솔 출력 같은 원래 동작은 그대로 남는다
  • 콘솔에 붙여 넣은 코드는 새로 고치면 사라진다. 자주 쓰면 크롬·엣지 개발자도구의 Sources → Snippets 에 저장해 두고 필요할 때 실행하면 편하다
  • 넥사크로가 남기는 경고(위 예의 focus failure 같은 것)는 자바스크립트 예외가 아니라 트레이스 로그로만 나온다. 그래서 트레이스 로그와 error 이벤트를 둘 다 건다

다시 쓰며 바로잡은 점

  • 원문은 같은 토스트 함수를 세 번 복사해 넣었고, _writeTraceLog 를 원래 구현을 베껴서 통째로 바꿔치기했다. 토스트 함수를 하나로 합치고, 원래 함수를 감싸서 부르도록 고쳐 버전이 달라도 원래 동작이 깨지지 않게 했다
  • window.onerror 대입 대신 addEventListener("error", ...) 를 써서 페이지에 이미 걸린 오류 처리기를 덮어쓰지 않게 했다
  • 내부 함수라는 점과 운영 코드에 넣지 말라는 주의를 덧붙였다