Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9347845
utils.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
utils.js
View Options
import
{
getGlobalObject
,
isNativeFetch
,
logger
,
supportsFetch
}
from
'@sentry/utils'
;
var
global
=
getGlobalObject
();
let
cachedFetchImpl
;
/**
* A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.
* Whenever someone wraps the Fetch API and returns the wrong promise chain,
* this chain becomes orphaned and there is no possible way to capture it's rejections
* other than allowing it bubble up to this very handler. eg.
*
* var f = window.fetch;
* window.fetch = function () {
* var p = f.apply(this, arguments);
*
* p.then(function() {
* console.log('hi.');
* });
*
* return p;
* }
*
* `p.then(function () { ... })` is producing a completely separate promise chain,
* however, what's returned is `p` - the result of original `fetch` call.
*
* This mean, that whenever we use the Fetch API to send our own requests, _and_
* some ad-blocker blocks it, this orphaned chain will _always_ reject,
* effectively causing another event to be captured.
* This makes a whole process become an infinite loop, which we need to somehow
* deal with, and break it in one way or another.
*
* To deal with this issue, we are making sure that we _always_ use the real
* browser Fetch API, instead of relying on what `window.fetch` exposes.
* The only downside to this would be missing our own requests as breadcrumbs,
* but because we are already not doing this, it should be just fine.
*
* Possible failed fetch error messages per-browser:
*
* Chrome: Failed to fetch
* Edge: Failed to Fetch
* Firefox: NetworkError when attempting to fetch resource
* Safari: resource blocked by content blocker
*/
function
getNativeFetchImplementation
()
{
if
(
cachedFetchImpl
)
{
return
cachedFetchImpl
;
}
// Fast path to avoid DOM I/O
if
(
isNativeFetch
(
global
.
fetch
))
{
return
(
cachedFetchImpl
=
global
.
fetch
.
bind
(
global
));
}
var
document
=
global
.
document
;
let
fetchImpl
=
global
.
fetch
;
if
(
document
&&
typeof
document
.
createElement
===
'function'
)
{
try
{
var
sandbox
=
document
.
createElement
(
'iframe'
);
sandbox
.
hidden
=
true
;
document
.
head
.
appendChild
(
sandbox
);
var
contentWindow
=
sandbox
.
contentWindow
;
if
(
contentWindow
&&
contentWindow
.
fetch
)
{
fetchImpl
=
contentWindow
.
fetch
;
}
document
.
head
.
removeChild
(
sandbox
);
}
catch
(
e
)
{
(
typeof
__SENTRY_DEBUG__
===
'undefined'
||
__SENTRY_DEBUG__
)
&&
logger
.
warn
(
'Could not create sandbox iframe for pure fetch check, bailing to window.fetch: '
,
e
);
}
}
return
(
cachedFetchImpl
=
fetchImpl
.
bind
(
global
));
}
/**
* Sends sdk client report using sendBeacon or fetch as a fallback if available
*
* @param url report endpoint
* @param body report payload
*/
function
sendReport
(
url
,
body
)
{
var
isRealNavigator
=
Object
.
prototype
.
toString
.
call
(
global
&&
global
.
navigator
)
===
'[object Navigator]'
;
var
hasSendBeacon
=
isRealNavigator
&&
typeof
global
.
navigator
.
sendBeacon
===
'function'
;
if
(
hasSendBeacon
)
{
// Prevent illegal invocations - https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch
var
sendBeacon
=
global
.
navigator
.
sendBeacon
.
bind
(
global
.
navigator
);
sendBeacon
(
url
,
body
);
}
else
if
(
supportsFetch
())
{
var
fetch
=
getNativeFetchImplementation
();
fetch
(
url
,
{
body
,
method
:
'POST'
,
credentials
:
'omit'
,
keepalive
:
true
,
}).
then
(
null
,
error
=>
{
(
typeof
__SENTRY_DEBUG__
===
'undefined'
||
__SENTRY_DEBUG__
)
&&
logger
.
error
(
error
);
});
}
}
export
{
getNativeFetchImplementation
,
sendReport
};
//# sourceMappingURL=utils.js.map
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Jul 4 2025, 5:58 PM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3315311
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment