error-flux
Version:
Network request interceptor and logger for web applications
4 lines (3 loc) • 12.4 kB
JavaScript
var $=Object.defineProperty;var U=Object.getOwnPropertySymbols;var V=Object.prototype.hasOwnProperty,M=Object.prototype.propertyIsEnumerable;var O=(t,e,r)=>e in t?$(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,h=(t,e)=>{for(var r in e||(e={}))V.call(e,r)&&O(t,r,e[r]);if(U)for(var r of U(e))M.call(e,r)&&O(t,r,e[r]);return t};var l=(t,e,r)=>new Promise((n,o)=>{var a=c=>{try{s(r.next(c))}catch(d){o(d)}},i=c=>{try{s(r.throw(c))}catch(d){o(d)}},s=c=>c.done?n(c.value):Promise.resolve(c.value).then(a,i);s((r=r.apply(t,e)).next())});var G={dbName:"ErrorFluxDB",storeName:{networkLogs:"networkLogs",consoleErrors:"consoleErrors",unhandledErrors:"unhandledErrors"},pattern:".*",allowOnlyNetworkErrors:!0,storageType:"indexedDB"},x=class{constructor(e){this.listeners=[];this.state=h(h({},G),e)}getState(){return h({},this.state)}setState(e){this.state=h(h({},this.state),e),this.notifyListeners()}subscribe(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(r=>r!==e)}}notifyListeners(){this.listeners.forEach(e=>e(this.getState()))}},W=new x,u=W;var p=[];for(let t=0;t<256;++t)p.push((t+256).toString(16).slice(1));function T(t,e=0){return(p[t[e+0]]+p[t[e+1]]+p[t[e+2]]+p[t[e+3]]+"-"+p[t[e+4]]+p[t[e+5]]+"-"+p[t[e+6]]+p[t[e+7]]+"-"+p[t[e+8]]+p[t[e+9]]+"-"+p[t[e+10]]+p[t[e+11]]+p[t[e+12]]+p[t[e+13]]+p[t[e+14]]+p[t[e+15]]).toLowerCase()}var k,z=new Uint8Array(16);function L(){if(!k){if(typeof crypto=="undefined"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");k=crypto.getRandomValues.bind(crypto)}return k(z)}var K=typeof crypto!="undefined"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),I={randomUUID:K};function Q(t,e,r){var o,a,i;if(I.randomUUID&&!e&&!t)return I.randomUUID();t=t||{};let n=(i=(a=t.random)!=null?a:(o=t.rng)==null?void 0:o.call(t))!=null?i:L();if(n.length<16)throw new Error("Random bytes length must be >= 16");if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,e){if(r=r||0,r<0||r+16>e.length)throw new RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let s=0;s<16;++s)e[r+s]=n[s];return e}return T(n)}var D=Q;function S(){return D()}function w(t,e,r=1){return l(this,null,function*(){return new Promise((n,o)=>{let a=indexedDB.open(t,r);a.onerror=()=>{o(new Error("Failed to open database"))},a.onsuccess=i=>{n(i.target.result)},a.onupgradeneeded=i=>{let s=i.target.result;Object.values(e).forEach(c=>{s.objectStoreNames.contains(c)||s.createObjectStore(c,{keyPath:"id"})})}})})}function R(t){return l(this,null,function*(){let{dbName:e,storeName:r}=u.getState(),n=yield w(e,r);return new Promise((o,a)=>{let s=n.transaction([r.networkLogs],"readwrite").objectStore(r.networkLogs),c={id:S(),logs:t},d=s.add(c);d.onsuccess=()=>o(),d.onerror=()=>a(new Error("Failed to save logs"))})})}function N(){return l(this,null,function*(){let{dbName:t,storeName:e}=u.getState(),r=yield w(t,e);return new Promise((n,o)=>{let s=r.transaction([e.networkLogs],"readonly").objectStore(e.networkLogs).getAll();s.onsuccess=()=>n(s.result),s.onerror=()=>o(new Error("Failed to retrieve logs"))})})}function B(t){return l(this,null,function*(){let{dbName:e,storeName:r}=u.getState(),n=yield w(e,r);return new Promise((o,a)=>{let s=n.transaction([r.consoleErrors],"readwrite").objectStore(r.consoleErrors),c={id:S(),errors:t},d=s.add(c);d.onsuccess=()=>o(),d.onerror=()=>a(new Error("Failed to save console errors"))})})}function F(){return l(this,null,function*(){let{dbName:t,storeName:e}=u.getState(),r=yield w(t,e);return new Promise((n,o)=>{let s=r.transaction([e.consoleErrors],"readonly").objectStore(e.consoleErrors).getAll();s.onsuccess=()=>n(s.result),s.onerror=()=>o(new Error("Failed to retrieve console errors"))})})}function j(t){return l(this,null,function*(){let{dbName:e,storeName:r}=u.getState(),n=yield w(e,r);return new Promise((o,a)=>{let s=n.transaction([r.unhandledErrors],"readwrite").objectStore(r.unhandledErrors),c={id:S(),errors:t},d=s.add(c);d.onsuccess=()=>o(),d.onerror=()=>a(new Error("Failed to save unhandled errors"))})})}function q(){return l(this,null,function*(){let{dbName:t,storeName:e}=u.getState(),r=yield w(t,e);return new Promise((n,o)=>{let s=r.transaction([e.unhandledErrors],"readonly").objectStore(e.unhandledErrors).getAll();s.onsuccess=()=>n(s.result),s.onerror=()=>o(new Error("Failed to retrieve unhandled errors"))})})}function y(t,e={}){if(typeof window!="undefined"&&"requestIdleCallback"in window){let r=window.requestIdleCallback(n=>{n.timeRemaining()>0||n.didTimeout?t():y(t,e)},{timeout:e.timeout||1e3});return()=>{window.cancelIdleCallback(r)}}else{let r=setTimeout(()=>{t()},0);return()=>{clearTimeout(r)}}}var v=()=>u.getState().storeName.consoleErrors,P=()=>u.getState().storeName.unhandledErrors,J=()=>u.getState().dbName;var C={saveError(t,e){return l(this,null,function*(){y(()=>l(this,null,function*(){let{dbName:r,storageType:n}=u.getState();switch(n){case"localStorage":try{let o=JSON.parse(localStorage.getItem(r)||"{}"),a=o[t]||[];a.push({id:S(),errors:e,timestamp:new Date().toISOString()}),o[t]=a,localStorage.setItem(r,JSON.stringify(o))}catch(o){console.warn("Failed to save to localStorage:",o)}break;case"sessionStorage":try{let o=JSON.parse(sessionStorage.getItem(r)||"{}"),a=o[t]||[];a.push({id:S(),errors:e,timestamp:new Date().toISOString()}),o[t]=a,sessionStorage.setItem(r,JSON.stringify(o))}catch(o){console.warn("Failed to save to sessionStorage:",o)}break;case"indexedDB":t===v()?yield B(e):t===P()&&(yield j(e));break}}))})}},Y=({handleOnError:t,handleOnUnhandledRejection:e})=>(t&&(window.onerror=function(n,o,a,i,s){let c=[{type:"synchronous",message:n,source:o,lineno:a,colno:i,stack:(s==null?void 0:s.stack)||String(s),timestamp:new Date().toISOString()}];C.saveError(v(),c)}),e&&window.addEventListener("unhandledrejection",function(n){var a,i,s,c,d;let o=[{type:"promise",message:((a=n.reason)==null?void 0:a.message)||"Unhandled Promise Rejection",source:((i=n.reason)==null?void 0:i.fileName)||"unknown",lineno:((s=n.reason)==null?void 0:s.lineNumber)||0,colno:((c=n.reason)==null?void 0:c.columnNumber)||0,stack:((d=n.reason)==null?void 0:d.stack)||String(n.reason),timestamp:new Date().toISOString()}];C.saveError(u.getState().storeName.unhandledErrors,o)}),{getLogs:()=>{let{storeName:n,dbName:o,storageType:a}=u.getState(),i=n.consoleErrors,s=n.unhandledErrors,c=()=>l(void 0,null,function*(){var g,m;switch(a){case"indexedDB":return yield c();case"localStorage":return((g=JSON.parse(localStorage.getItem(o)||"{}"))==null?void 0:g[i])||[];case"sessionStorage":return((m=JSON.parse(sessionStorage.getItem(o)||"{}"))==null?void 0:m[i])||[];default:return[]}}),d=()=>l(void 0,null,function*(){var g,m;switch(a){case"indexedDB":return yield d();case"localStorage":return((g=JSON.parse(localStorage.getItem(o)||"{}"))==null?void 0:g[s])||[];case"sessionStorage":return((m=JSON.parse(sessionStorage.getItem(o)||"{}"))==null?void 0:m[s])||[];default:return[]}});return{getConsoleErrors:c,getUnhandledErrors:d}}}),H=Y;function Z(t){let e={},r=t.getAllResponseHeaders().trim().split(`
`);for(let n=0;n<r.length;n++){let o=r[n].trim().split(": "),a=o[0],i=o[1];e[a]=i}return e}function _(){return S()}var E={push(t){return l(this,null,function*(){y(()=>l(this,null,function*(){let{storeName:e,dbName:r,storageType:n}=u.getState(),o=e.networkLogs;switch(n){case"localStorage":try{let a=JSON.parse(localStorage.getItem(r)||"{}"),i=a[o]||[];i.push(t),a[o]=i,localStorage.setItem(r,JSON.stringify(a))}catch(a){console.warn("Failed to save to localStorage:",a)}break;case"sessionStorage":try{let a=JSON.parse(sessionStorage.getItem(r)||"{}"),i=a[o]||[];i.push(t),a[o]=i,sessionStorage.setItem(r,JSON.stringify(a))}catch(a){console.warn("Failed to save to sessionStorage:",a)}break;case"indexedDB":yield R(t);break}}))})}},ee=({pattern:t,onlyFailures:e=!1})=>{let r=window.fetch,n=window.XMLHttpRequest;window.fetch=function(i,s){return l(this,null,function*(){let c=_(),d=performance.now();return r(i,s).then(g=>l(this,null,function*(){let m=g.clone(),A=yield m.text();return m.url.match(t)&&(!e||e&&!m.ok)&&E.push({id:c,type:"fetch",url:typeof i=="string"?i:i.toString(),method:(s==null?void 0:s.method)||"GET",requestHeaders:s!=null&&s.headers?Object.fromEntries(new Headers(s.headers).entries()):{},requestBody:(s==null?void 0:s.body)||null,responseHeaders:Object.fromEntries(m.headers.entries()),responseBody:A,status:m.status,duration:performance.now()-d,success:m.ok,cookies:document.cookie}),g})).catch(g=>{let m=g instanceof TypeError?0:g.status||g.response&&g.response.status||500;throw g.response.url.match(t)&&E.push({id:c,type:"fetch",url:typeof i=="string"?i:i.toString(),method:(s==null?void 0:s.method)||"GET",error:g.message,duration:performance.now()-d,success:!1,requestBody:null,status:m,cookies:document.cookie}),g})})};class o extends n{constructor(){super(),this.requestId=_(),this.startTime=null,this._url="",this._method="",this._error=null}open(s,c,...d){this._method=s,this._url=c,super.open(s,c,...d)}send(s){this.startTime=performance.now(),this.addEventListener("loadend",()=>{let c=!(this.status>=200&&this.status<300);!this._url.match(t)||e&&!c||E.push({id:this.requestId,type:"xhr",url:this._url,method:this._method,requestBody:s||null,responseHeaders:Z(this),responseBody:this.responseText,status:this.status,duration:performance.now()-this.startTime,success:!c,cookies:document.cookie})}),this.addEventListener("error",()=>{this._url.match(t)&&E.push({id:this.requestId,type:"xhr",url:this._url,method:this._method,error:"Network error",duration:performance.now()-this.startTime,success:!1,requestBody:null,cookies:document.cookie,status:this.status})}),super.send(s)}}return window.XMLHttpRequest=o,{getLogs:()=>l(void 0,null,function*(){var g,m;let{storeName:i,dbName:s,storageType:c}=u.getState(),d=i.networkLogs;switch(c){case"indexedDB":return yield N();case"localStorage":return((g=JSON.parse(localStorage.getItem(s)||"{}"))==null?void 0:g[d])||[];case"sessionStorage":return((m=JSON.parse(sessionStorage.getItem(s)||"{}"))==null?void 0:m[d])||[]}})}},X=ee;function f(t,e="data.json"){let r=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),n=URL.createObjectURL(r),o=document.createElement("a");o.href=n,o.download=e,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}var te=()=>l(void 0,null,function*(){let t=()=>l(void 0,null,function*(){var a,i;let{storeName:e,dbName:r,storageType:n}=u.getState(),o=e.networkLogs;switch(n){case"indexedDB":return yield N();case"localStorage":return((a=JSON.parse(localStorage.getItem(r)||"{}"))==null?void 0:a[o])||[];case"sessionStorage":return((i=JSON.parse(sessionStorage.getItem(r)||"{}"))==null?void 0:i[o])||[]}});try{let e=yield t();f({type:"Network",logs:e},`Network_${new Date().getTime()}`)}catch(e){}}),re=()=>l(void 0,null,function*(){let t=()=>l(void 0,null,function*(){var a,i;let{storeName:e,dbName:r,storageType:n}=u.getState(),o=e.consoleErrors;switch(n){case"indexedDB":return yield F();case"localStorage":return((a=JSON.parse(localStorage.getItem(r)||"{}"))==null?void 0:a[o])||[];case"sessionStorage":return((i=JSON.parse(sessionStorage.getItem(r)||"{}"))==null?void 0:i[o])||[]}});try{let e=yield t();f({type:"Errors",logs:e},`Errors_${new Date().getTime()}`)}catch(e){}}),oe=()=>l(void 0,null,function*(){let t=()=>l(void 0,null,function*(){var a,i;let{storeName:e,dbName:r,storageType:n}=u.getState(),o=e.unhandledErrors;switch(n){case"indexedDB":return yield q();case"localStorage":return((a=JSON.parse(localStorage.getItem(r)||"{}"))==null?void 0:a[o])||[];case"sessionStorage":return((i=JSON.parse(sessionStorage.getItem(r)||"{}"))==null?void 0:i[o])||[]}});try{let e=yield t();f({type:"UnhandledRejections",logs:e},`UnhandledRejections_${new Date().getTime()}`)}catch(e){}});function se({pattern:t,allowOnlyNetworkErrors:e=!0,storeName:r,dbName:n,storageType:o,handleOnError:a,handleOnUnhandledRejection:i}){u.setState({dbName:n||J(),storageType:o||u.getState().storageType,storeName:h(h({},u.getState().storeName),Object.keys(r||{}).length>0?r:{})});let{getLogs:s}=X({pattern:t,onlyFailures:e}),{getLogs:c}=H({handleOnError:a,handleOnUnhandledRejection:i});return{getNetworkLogs:s,getErrorLogs:c}}export{se as default,re as downloadConsoleErrors,te as downloadNetworkLogs,oe as downloadUnhandledErrors};
//# sourceMappingURL=errorflux.esm.js.map