Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F8322511
baseclient.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Subscribers
None
baseclient.js
View Options
import
{
__assign
,
__values
}
from
"tslib"
;
/* eslint-disable max-lines */
import
{
Scope
}
from
'@sentry/hub'
;
import
{
SessionStatus
,
}
from
'@sentry/types'
;
import
{
dateTimestampInSeconds
,
Dsn
,
isPrimitive
,
isThenable
,
logger
,
normalize
,
SentryError
,
SyncPromise
,
truncate
,
uuid4
,
}
from
'@sentry/utils'
;
import
{
setupIntegrations
}
from
'./integration'
;
/**
* Base implementation for all JavaScript SDK clients.
*
* Call the constructor with the corresponding backend constructor and options
* specific to the client subclass. To access these options later, use
* {@link Client.getOptions}. Also, the Backend instance is available via
* {@link Client.getBackend}.
*
* If a Dsn is specified in the options, it will be parsed and stored. Use
* {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is
* invalid, the constructor will throw a {@link SentryException}. Note that
* without a valid Dsn, the SDK will not send any events to Sentry.
*
* Before sending an event via the backend, it is passed through
* {@link BaseClient._prepareEvent} to add SDK information and scope data
* (breadcrumbs and context). To add more custom information, override this
* method and extend the resulting prepared event.
*
* To issue automatically created events (e.g. via instrumentation), use
* {@link Client.captureEvent}. It will prepare the event and pass it through
* the callback lifecycle. To issue auto-breadcrumbs, use
* {@link Client.addBreadcrumb}.
*
* @example
* class NodeClient extends BaseClient<NodeBackend, NodeOptions> {
* public constructor(options: NodeOptions) {
* super(NodeBackend, options);
* }
*
* // ...
* }
*/
var
BaseClient
=
/** @class */
(
function
()
{
/**
* Initializes this client instance.
*
* @param backendClass A constructor function to create the backend.
* @param options Options for the client.
*/
function
BaseClient
(
backendClass
,
options
)
{
/** Array of used integrations. */
this
.
_integrations
=
{};
/** Number of call being processed */
this
.
_processing
=
0
;
this
.
_backend
=
new
backendClass
(
options
);
this
.
_options
=
options
;
if
(
options
.
dsn
)
{
this
.
_dsn
=
new
Dsn
(
options
.
dsn
);
}
}
/**
* @inheritDoc
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
BaseClient
.
prototype
.
captureException
=
function
(
exception
,
hint
,
scope
)
{
var
_this
=
this
;
var
eventId
=
hint
&&
hint
.
event_id
;
this
.
_process
(
this
.
_getBackend
()
.
eventFromException
(
exception
,
hint
)
.
then
(
function
(
event
)
{
return
_this
.
_captureEvent
(
event
,
hint
,
scope
);
})
.
then
(
function
(
result
)
{
eventId
=
result
;
}));
return
eventId
;
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
captureMessage
=
function
(
message
,
level
,
hint
,
scope
)
{
var
_this
=
this
;
var
eventId
=
hint
&&
hint
.
event_id
;
var
promisedEvent
=
isPrimitive
(
message
)
?
this
.
_getBackend
().
eventFromMessage
(
String
(
message
),
level
,
hint
)
:
this
.
_getBackend
().
eventFromException
(
message
,
hint
);
this
.
_process
(
promisedEvent
.
then
(
function
(
event
)
{
return
_this
.
_captureEvent
(
event
,
hint
,
scope
);
})
.
then
(
function
(
result
)
{
eventId
=
result
;
}));
return
eventId
;
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
captureEvent
=
function
(
event
,
hint
,
scope
)
{
var
eventId
=
hint
&&
hint
.
event_id
;
this
.
_process
(
this
.
_captureEvent
(
event
,
hint
,
scope
).
then
(
function
(
result
)
{
eventId
=
result
;
}));
return
eventId
;
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
captureSession
=
function
(
session
)
{
if
(
!
session
.
release
)
{
logger
.
warn
(
'Discarded session because of missing release'
);
}
else
{
this
.
_sendSession
(
session
);
// After sending, we set init false to inidcate it's not the first occurence
session
.
update
({
init
:
false
});
}
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
getDsn
=
function
()
{
return
this
.
_dsn
;
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
getOptions
=
function
()
{
return
this
.
_options
;
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
flush
=
function
(
timeout
)
{
var
_this
=
this
;
return
this
.
_isClientProcessing
(
timeout
).
then
(
function
(
ready
)
{
return
_this
.
_getBackend
()
.
getTransport
()
.
close
(
timeout
)
.
then
(
function
(
transportFlushed
)
{
return
ready
&&
transportFlushed
;
});
});
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
close
=
function
(
timeout
)
{
var
_this
=
this
;
return
this
.
flush
(
timeout
).
then
(
function
(
result
)
{
_this
.
getOptions
().
enabled
=
false
;
return
result
;
});
};
/**
* Sets up the integrations
*/
BaseClient
.
prototype
.
setupIntegrations
=
function
()
{
if
(
this
.
_isEnabled
())
{
this
.
_integrations
=
setupIntegrations
(
this
.
_options
);
}
};
/**
* @inheritDoc
*/
BaseClient
.
prototype
.
getIntegration
=
function
(
integration
)
{
try
{
return
this
.
_integrations
[
integration
.
id
]
||
null
;
}
catch
(
_oO
)
{
logger
.
warn
(
"Cannot retrieve integration "
+
integration
.
id
+
" from the current Client"
);
return
null
;
}
};
/** Updates existing session based on the provided event */
BaseClient
.
prototype
.
_updateSessionFromEvent
=
function
(
session
,
event
)
{
var
e_1
,
_a
;
var
crashed
=
false
;
var
errored
=
false
;
var
userAgent
;
var
exceptions
=
event
.
exception
&&
event
.
exception
.
values
;
if
(
exceptions
)
{
errored
=
true
;
try
{
for
(
var
exceptions_1
=
__values
(
exceptions
),
exceptions_1_1
=
exceptions_1
.
next
();
!
exceptions_1_1
.
done
;
exceptions_1_1
=
exceptions_1
.
next
())
{
var
ex
=
exceptions_1_1
.
value
;
var
mechanism
=
ex
.
mechanism
;
if
(
mechanism
&&
mechanism
.
handled
===
false
)
{
crashed
=
true
;
break
;
}
}
}
catch
(
e_1_1
)
{
e_1
=
{
error
:
e_1_1
};
}
finally
{
try
{
if
(
exceptions_1_1
&&
!
exceptions_1_1
.
done
&&
(
_a
=
exceptions_1
.
return
))
_a
.
call
(
exceptions_1
);
}
finally
{
if
(
e_1
)
throw
e_1
.
error
;
}
}
}
var
user
=
event
.
user
;
if
(
!
session
.
userAgent
)
{
var
headers
=
event
.
request
?
event
.
request
.
headers
:
{};
for
(
var
key
in
headers
)
{
if
(
key
.
toLowerCase
()
===
'user-agent'
)
{
userAgent
=
headers
[
key
];
break
;
}
}
}
session
.
update
(
__assign
(
__assign
({},
(
crashed
&&
{
status
:
SessionStatus
.
Crashed
})),
{
user
:
user
,
userAgent
:
userAgent
,
errors
:
session
.
errors
+
Number
(
errored
||
crashed
)
}));
this
.
captureSession
(
session
);
};
/** Deliver captured session to Sentry */
BaseClient
.
prototype
.
_sendSession
=
function
(
session
)
{
this
.
_getBackend
().
sendSession
(
session
);
};
/** Waits for the client to be done with processing. */
BaseClient
.
prototype
.
_isClientProcessing
=
function
(
timeout
)
{
var
_this
=
this
;
return
new
SyncPromise
(
function
(
resolve
)
{
var
ticked
=
0
;
var
tick
=
1
;
var
interval
=
setInterval
(
function
()
{
if
(
_this
.
_processing
==
0
)
{
clearInterval
(
interval
);
resolve
(
true
);
}
else
{
ticked
+=
tick
;
if
(
timeout
&&
ticked
>=
timeout
)
{
clearInterval
(
interval
);
resolve
(
false
);
}
}
},
tick
);
});
};
/** Returns the current backend. */
BaseClient
.
prototype
.
_getBackend
=
function
()
{
return
this
.
_backend
;
};
/** Determines whether this SDK is enabled and a valid Dsn is present. */
BaseClient
.
prototype
.
_isEnabled
=
function
()
{
return
this
.
getOptions
().
enabled
!==
false
&&
this
.
_dsn
!==
undefined
;
};
/**
* Adds common information to events.
*
* The information includes release and environment from `options`,
* breadcrumbs and context (extra, tags and user) from the scope.
*
* Information that is already present in the event is never overwritten. For
* nested objects, such as the context, keys are merged.
*
* @param event The original event.
* @param hint May contain additional information about the original exception.
* @param scope A scope containing event metadata.
* @returns A new event with more information.
*/
BaseClient
.
prototype
.
_prepareEvent
=
function
(
event
,
scope
,
hint
)
{
var
_this
=
this
;
var
_a
=
this
.
getOptions
().
normalizeDepth
,
normalizeDepth
=
_a
===
void
0
?
3
:
_a
;
var
prepared
=
__assign
(
__assign
({},
event
),
{
event_id
:
event
.
event_id
||
(
hint
&&
hint
.
event_id
?
hint
.
event_id
:
uuid4
()),
timestamp
:
event
.
timestamp
||
dateTimestampInSeconds
()
});
this
.
_applyClientOptions
(
prepared
);
this
.
_applyIntegrationsMetadata
(
prepared
);
// If we have scope given to us, use it as the base for further modifications.
// This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
var
finalScope
=
scope
;
if
(
hint
&&
hint
.
captureContext
)
{
finalScope
=
Scope
.
clone
(
finalScope
).
update
(
hint
.
captureContext
);
}
// We prepare the result here with a resolved Event.
var
result
=
SyncPromise
.
resolve
(
prepared
);
// This should be the last thing called, since we want that
// {@link Hub.addEventProcessor} gets the finished prepared event.
if
(
finalScope
)
{
// In case we have a hub we reassign it.
result
=
finalScope
.
applyToEvent
(
prepared
,
hint
);
}
return
result
.
then
(
function
(
evt
)
{
if
(
typeof
normalizeDepth
===
'number'
&&
normalizeDepth
>
0
)
{
return
_this
.
_normalizeEvent
(
evt
,
normalizeDepth
);
}
return
evt
;
});
};
/**
* Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.
* Normalized keys:
* - `breadcrumbs.data`
* - `user`
* - `contexts`
* - `extra`
* @param event Event
* @returns Normalized event
*/
BaseClient
.
prototype
.
_normalizeEvent
=
function
(
event
,
depth
)
{
if
(
!
event
)
{
return
null
;
}
var
normalized
=
__assign
(
__assign
(
__assign
(
__assign
(
__assign
({},
event
),
(
event
.
breadcrumbs
&&
{
breadcrumbs
:
event
.
breadcrumbs
.
map
(
function
(
b
)
{
return
(
__assign
(
__assign
({},
b
),
(
b
.
data
&&
{
data
:
normalize
(
b
.
data
,
depth
),
})));
}),
})),
(
event
.
user
&&
{
user
:
normalize
(
event
.
user
,
depth
),
})),
(
event
.
contexts
&&
{
contexts
:
normalize
(
event
.
contexts
,
depth
),
})),
(
event
.
extra
&&
{
extra
:
normalize
(
event
.
extra
,
depth
),
}));
// event.contexts.trace stores information about a Transaction. Similarly,
// event.spans[] stores information about child Spans. Given that a
// Transaction is conceptually a Span, normalization should apply to both
// Transactions and Spans consistently.
// For now the decision is to skip normalization of Transactions and Spans,
// so this block overwrites the normalized event to add back the original
// Transaction information prior to normalization.
if
(
event
.
contexts
&&
event
.
contexts
.
trace
)
{
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
normalized
.
contexts
.
trace
=
event
.
contexts
.
trace
;
}
return
normalized
;
};
/**
* Enhances event using the client configuration.
* It takes care of all "static" values like environment, release and `dist`,
* as well as truncating overly long values.
* @param event event instance to be enhanced
*/
BaseClient
.
prototype
.
_applyClientOptions
=
function
(
event
)
{
var
options
=
this
.
getOptions
();
var
environment
=
options
.
environment
,
release
=
options
.
release
,
dist
=
options
.
dist
,
_a
=
options
.
maxValueLength
,
maxValueLength
=
_a
===
void
0
?
250
:
_a
;
if
(
!
(
'environment'
in
event
))
{
event
.
environment
=
'environment'
in
options
?
environment
:
'production'
;
}
if
(
event
.
release
===
undefined
&&
release
!==
undefined
)
{
event
.
release
=
release
;
}
if
(
event
.
dist
===
undefined
&&
dist
!==
undefined
)
{
event
.
dist
=
dist
;
}
if
(
event
.
message
)
{
event
.
message
=
truncate
(
event
.
message
,
maxValueLength
);
}
var
exception
=
event
.
exception
&&
event
.
exception
.
values
&&
event
.
exception
.
values
[
0
];
if
(
exception
&&
exception
.
value
)
{
exception
.
value
=
truncate
(
exception
.
value
,
maxValueLength
);
}
var
request
=
event
.
request
;
if
(
request
&&
request
.
url
)
{
request
.
url
=
truncate
(
request
.
url
,
maxValueLength
);
}
};
/**
* This function adds all used integrations to the SDK info in the event.
* @param event The event that will be filled with all integrations.
*/
BaseClient
.
prototype
.
_applyIntegrationsMetadata
=
function
(
event
)
{
var
sdkInfo
=
event
.
sdk
;
var
integrationsArray
=
Object
.
keys
(
this
.
_integrations
);
if
(
sdkInfo
&&
integrationsArray
.
length
>
0
)
{
sdkInfo
.
integrations
=
integrationsArray
;
}
};
/**
* Tells the backend to send this event
* @param event The Sentry event to send
*/
BaseClient
.
prototype
.
_sendEvent
=
function
(
event
)
{
this
.
_getBackend
().
sendEvent
(
event
);
};
/**
* Processes the event and logs an error in case of rejection
* @param event
* @param hint
* @param scope
*/
BaseClient
.
prototype
.
_captureEvent
=
function
(
event
,
hint
,
scope
)
{
return
this
.
_processEvent
(
event
,
hint
,
scope
).
then
(
function
(
finalEvent
)
{
return
finalEvent
.
event_id
;
},
function
(
reason
)
{
logger
.
error
(
reason
);
return
undefined
;
});
};
/**
* Processes an event (either error or message) and sends it to Sentry.
*
* This also adds breadcrumbs and context information to the event. However,
* platform specific meta data (such as the User's IP address) must be added
* by the SDK implementor.
*
*
* @param event The event to send to Sentry.
* @param hint May contain additional information about the original exception.
* @param scope A scope containing event metadata.
* @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.
*/
BaseClient
.
prototype
.
_processEvent
=
function
(
event
,
hint
,
scope
)
{
var
_this
=
this
;
// eslint-disable-next-line @typescript-eslint/unbound-method
var
_a
=
this
.
getOptions
(),
beforeSend
=
_a
.
beforeSend
,
sampleRate
=
_a
.
sampleRate
;
if
(
!
this
.
_isEnabled
())
{
return
SyncPromise
.
reject
(
new
SentryError
(
'SDK not enabled, will not send event.'
));
}
var
isTransaction
=
event
.
type
===
'transaction'
;
// 1.0 === 100% events are sent
// 0.0 === 0% events are sent
// Sampling for transaction happens somewhere else
if
(
!
isTransaction
&&
typeof
sampleRate
===
'number'
&&
Math
.
random
()
>
sampleRate
)
{
return
SyncPromise
.
reject
(
new
SentryError
(
"Discarding event because it's not included in the random sample (sampling rate = "
+
sampleRate
+
")"
));
}
return
this
.
_prepareEvent
(
event
,
scope
,
hint
)
.
then
(
function
(
prepared
)
{
if
(
prepared
===
null
)
{
throw
new
SentryError
(
'An event processor returned null, will not send event.'
);
}
var
isInternalException
=
hint
&&
hint
.
data
&&
hint
.
data
.
__sentry__
===
true
;
if
(
isInternalException
||
isTransaction
||
!
beforeSend
)
{
return
prepared
;
}
var
beforeSendResult
=
beforeSend
(
prepared
,
hint
);
if
(
typeof
beforeSendResult
===
'undefined'
)
{
throw
new
SentryError
(
'`beforeSend` method has to return `null` or a valid event.'
);
}
else
if
(
isThenable
(
beforeSendResult
))
{
return
beforeSendResult
.
then
(
function
(
event
)
{
return
event
;
},
function
(
e
)
{
throw
new
SentryError
(
"beforeSend rejected with "
+
e
);
});
}
return
beforeSendResult
;
})
.
then
(
function
(
processedEvent
)
{
if
(
processedEvent
===
null
)
{
throw
new
SentryError
(
'`beforeSend` returned `null`, will not send event.'
);
}
var
session
=
scope
&&
scope
.
getSession
&&
scope
.
getSession
();
if
(
!
isTransaction
&&
session
)
{
_this
.
_updateSessionFromEvent
(
session
,
processedEvent
);
}
_this
.
_sendEvent
(
processedEvent
);
return
processedEvent
;
})
.
then
(
null
,
function
(
reason
)
{
if
(
reason
instanceof
SentryError
)
{
throw
reason
;
}
_this
.
captureException
(
reason
,
{
data
:
{
__sentry__
:
true
,
},
originalException
:
reason
,
});
throw
new
SentryError
(
"Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: "
+
reason
);
});
};
/**
* Occupies the client with processing and event
*/
BaseClient
.
prototype
.
_process
=
function
(
promise
)
{
var
_this
=
this
;
this
.
_processing
+=
1
;
promise
.
then
(
function
(
value
)
{
_this
.
_processing
-=
1
;
return
value
;
},
function
(
reason
)
{
_this
.
_processing
-=
1
;
return
reason
;
});
};
return
BaseClient
;
}());
export
{
BaseClient
};
//# sourceMappingURL=baseclient.js.map
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Tue, Jun 3, 7:36 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3328240
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment