JAVASCRIPT   18

er11 js

Guest on 4th July 2022 07:24:26 PM

  1. 'use strict';   // This is for ES11 aka ES2020
  2. // This Works is placed under the terms of the Copyright Less License,
  3. // see file COPYRIGHT.CLL.  USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
  4.  
  5. // Minimalistic global error catcher/reporter:
  6. // <script src="er11.js" data-post="https://error.example.com/errortarget" data-tag="sometag"></script>
  7. // <script src="er11.js" data-append="element-id" data-appendms="20000" data-noclick></script>
  8. // <script src="er11.js" data-debug="console-prefix"></script>
  9. // <script src="er11.js" data-call="function"></script>
  10.  
  11. const __CATCH__ = (f => f(document.currentScript?.dataset || {debug:'ER11'}, document.currentScript?.url))((ds,url) => {
  12.  
  13.   // __CATCH__(fn): calls fn(e,j) on errors, j is a JSON serializable object
  14.   const CATCH = fn =>
  15.     {
  16.       // a global catch for errors and unhandled rejections
  17.       let w = e => { const v=e.error || e.reason; try {
  18.         let o={type:e.toString?.()}
  19.         if (v?.stack) o.stack = v.stack;
  20.         else o.reason = e.reason;       // Without .catch(THROW) you do not get a stackframe from Promise.reject()!
  21.         if (v?.message) o.message = v.message;
  22.         ['filename','lineno','colno'].filter(_ => e[_]).forEach(_ => o[_]=e[_]);
  23.         fn(e, o);
  24.       } catch(e) { console.log?.('CATCHERR', e) } }
  25.       window.addEventListener('error',w,true);
  26.       window.addEventListener('unhandledrejection',w);
  27.       window.addEventListener('es11_catched_error_event',w);
  28.       // do we need even more?
  29.     }
  30.  
  31.   // Output to console: data-debug="prefix"
  32.   // For environments lacking console we should forward this problem to somewhere else.
  33.   if (ds.debug)
  34.     // Actually this is a BUG for environments lacking console.
  35.     // We should forward this problem to the other error handlers.
  36.     CATCH((e,d) => console.error?.(ds.debug,e,d));
  37.  
  38.   // Append <PRE> to some element: data-append="element-id"
  39.   // when clicked error message is copied to clipboard and removed
  40.   if (ds.append)
  41.     CATCH((e,d) =>
  42.       {
  43.         const f = r => (f => f(document.getElementById(ds.append)))(o =>
  44. //            { console.log('f', o,r,ds.ms); return (
  45.             o ? o.append(((f => f(document.createElement('PRE')))(l =>
  46.                 {
  47.                   l.innerText = Object.keys(d).map(k => `${k}: ${d[k]}`).join('\n');
  48.                   if (ds.ms != 0) setTimeout(() => l.remove(), parseInt(ds.ms) || 33333);
  49.                   if (!ds.noclick)
  50.                     l.onclick = () => { try { navigator.clipboard.writeText(l.innerText).then(() => l.remove()); } catch(e) { console.log('failed to copy error message to clip', e) }};
  51.                     return l;
  52.                 })))
  53.               : r ? setTimeout(f,r,r-1)
  54.               : 0
  55.                 // Actually this is a BUG:
  56.                 // If ID is not available we should throw.
  57.                 // However this would create a loop here,
  58.                 // so we somehow must evade this.
  59. //            )}
  60.           );
  61.         // try 100 times to get the element
  62.         setTimeout(f, 0, 100);
  63.       });
  64.  
  65.   // POST to some URL as JSON {e:{error-object}, t:tag}: data-post="URL" data-tag="tag"
  66.   if (ds.post)
  67.     {
  68.       const u = new URL(ds.post, new URL(url, window.location));
  69.       const t = ds.tag;
  70.       CATCH((_,e) => fetch(u,
  71.         { cache:'no-cache'
  72.         , method:'POST'
  73.         , headers:{'Content-Type':'application/json'}
  74.         , body:JSON.stringify({e, t})
  75.         }).then(r => { if (r.ok) return r.text();
  76.           throw new Error(`CATCH failed: ${r.url} failed with ${r.status}: ${r.statusText}`) })
  77.         .catch(console.log)
  78.         // Actually the .catch() before is a BUG:
  79.         // We shall throw errors to all other CATCH() handlers here that the POST did not work.
  80.         // Also we should retry after a little waiting time and give up at too many retries.
  81.         // This, however, needs to create some own clever Error object which is a lot of work.
  82.        );
  83.     }
  84.  
  85. //  if (ds.call)
  86. //    CATCH((e,d) => CALL(_ =>
  87. //      {
  88. //        while (!window[ds.call])
  89. //        if (d]); proc(calls, _ => window[ds.call](..._)));
  90. //      }
  91.  
  92.   return CATCH;
  93. });

Raw Paste


Login or Register to edit or fork this paste. It's free.