@boshyxd/rosentry 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/index.d.ts +32 -0
- package/out/init.luau +229 -0
- package/out/internal/AutoCapture.d.ts +13 -0
- package/out/internal/AutoCapture.luau +74 -0
- package/out/internal/Capture.d.ts +17 -0
- package/out/internal/Capture.luau +142 -0
- package/out/internal/Config.d.ts +12 -0
- package/out/internal/Config.luau +116 -0
- package/out/internal/Queue.d.ts +19 -0
- package/out/internal/Queue.luau +120 -0
- package/out/internal/Scope.d.ts +25 -0
- package/out/internal/Scope.luau +155 -0
- package/out/internal/Trace.d.ts +21 -0
- package/out/internal/Trace.luau +299 -0
- package/out/internal/Transport.d.ts +13 -0
- package/out/internal/Transport.luau +140 -0
- package/out/internal/util.d.ts +9 -0
- package/out/internal/util.luau +68 -0
- package/out/types.d.ts +94 -0
- package/out/types.luau +2 -0
- package/package.json +34 -0
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CaptureOptions, ConfigOptions, ScopeInterface, Trace, TraceOptions, TraceStatus } from "./types";
|
|
2
|
+
interface RoSentrySDK {
|
|
3
|
+
init(options: ConfigOptions): RoSentrySDK;
|
|
4
|
+
isInitialized(): boolean;
|
|
5
|
+
captureException(err: unknown, options?: CaptureOptions): string | undefined;
|
|
6
|
+
captureMessage(message: string, options?: CaptureOptions): string | undefined;
|
|
7
|
+
debug(message: string, data?: Map<string, unknown>): string | undefined;
|
|
8
|
+
info(message: string, data?: Map<string, unknown>): string | undefined;
|
|
9
|
+
warn(message: string, data?: Map<string, unknown>): string | undefined;
|
|
10
|
+
log(message: string, data?: Map<string, unknown>): string | undefined;
|
|
11
|
+
setUser(userId: number, playerName?: string, data?: Map<string, unknown>): void;
|
|
12
|
+
clearUser(): void;
|
|
13
|
+
addBreadcrumb(category: string, message: string, data?: Map<string, unknown>): void;
|
|
14
|
+
setTag(key: string, value: string): void;
|
|
15
|
+
setExtra(key: string, value: unknown): void;
|
|
16
|
+
wrap(fn: (...args: unknown[]) => unknown): (...args: unknown[]) => unknown;
|
|
17
|
+
withScope(callback: (scopeInterface: ScopeInterface) => void): void;
|
|
18
|
+
flush(): void;
|
|
19
|
+
enable(): void;
|
|
20
|
+
disable(): void;
|
|
21
|
+
getStatus(): {
|
|
22
|
+
initialized: boolean;
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
queueSize: number;
|
|
25
|
+
};
|
|
26
|
+
startTrace(traceName: string, options?: TraceOptions): Trace | undefined;
|
|
27
|
+
getTrace(traceId: string): Trace | undefined;
|
|
28
|
+
endAllTraces(status?: TraceStatus): void;
|
|
29
|
+
getActiveTraceCount(): number;
|
|
30
|
+
}
|
|
31
|
+
declare const RoSentry: RoSentrySDK;
|
|
32
|
+
export = RoSentry;
|
package/out/init.luau
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
4
|
+
local Config = TS.import(script, script, "internal", "Config").Config
|
|
5
|
+
local Transport = TS.import(script, script, "internal", "Transport").Transport
|
|
6
|
+
local Scope = TS.import(script, script, "internal", "Scope").Scope
|
|
7
|
+
local Queue = TS.import(script, script, "internal", "Queue").Queue
|
|
8
|
+
local Capture = TS.import(script, script, "internal", "Capture").Capture
|
|
9
|
+
local AutoCapture = TS.import(script, script, "internal", "AutoCapture").AutoCapture
|
|
10
|
+
local TraceManager = TS.import(script, script, "internal", "Trace").TraceManager
|
|
11
|
+
local IS_SERVER = RunService:IsServer()
|
|
12
|
+
local config
|
|
13
|
+
local transport
|
|
14
|
+
local scope
|
|
15
|
+
local queue
|
|
16
|
+
local capture
|
|
17
|
+
local autoCapture
|
|
18
|
+
local traceManager
|
|
19
|
+
local initialized = false
|
|
20
|
+
local function debugLog(...)
|
|
21
|
+
local args = { ... }
|
|
22
|
+
if config and config:get("debug") then
|
|
23
|
+
print("[RoSentry]", unpack(args))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
local function captureMessageImpl(message, options)
|
|
27
|
+
if not initialized then
|
|
28
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
29
|
+
return nil
|
|
30
|
+
end
|
|
31
|
+
return capture:captureMessage(message, options)
|
|
32
|
+
end
|
|
33
|
+
local RoSentry
|
|
34
|
+
RoSentry = {
|
|
35
|
+
init = function(self, options)
|
|
36
|
+
if initialized then
|
|
37
|
+
warn("[RoSentry] Already initialized")
|
|
38
|
+
return RoSentry
|
|
39
|
+
end
|
|
40
|
+
config = Config.new()
|
|
41
|
+
config:init(options, IS_SERVER)
|
|
42
|
+
transport = Transport.new(config)
|
|
43
|
+
scope = Scope.new(config)
|
|
44
|
+
queue = Queue.new(config, transport)
|
|
45
|
+
capture = Capture.new(config, scope, queue)
|
|
46
|
+
autoCapture = AutoCapture.new(config, capture)
|
|
47
|
+
traceManager = TraceManager.new(config, scope, queue)
|
|
48
|
+
if IS_SERVER then
|
|
49
|
+
transport:setupServerRelay()
|
|
50
|
+
end
|
|
51
|
+
queue:startFlushLoop()
|
|
52
|
+
if config:get("autoCapture") then
|
|
53
|
+
autoCapture:setup()
|
|
54
|
+
end
|
|
55
|
+
initialized = true
|
|
56
|
+
debugLog("Initialized with environment:", config:get("environment"), if IS_SERVER then "(server)" else "(client)")
|
|
57
|
+
scope:addBreadcrumb("sdk", "RoSentry initialized", {
|
|
58
|
+
environment = config:get("environment"),
|
|
59
|
+
placeId = game.PlaceId,
|
|
60
|
+
})
|
|
61
|
+
return RoSentry
|
|
62
|
+
end,
|
|
63
|
+
isInitialized = function(self)
|
|
64
|
+
return initialized
|
|
65
|
+
end,
|
|
66
|
+
captureException = function(self, err, options)
|
|
67
|
+
if not initialized then
|
|
68
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
69
|
+
return nil
|
|
70
|
+
end
|
|
71
|
+
return capture:captureException(err, options)
|
|
72
|
+
end,
|
|
73
|
+
captureMessage = function(self, message, options)
|
|
74
|
+
return captureMessageImpl(message, options)
|
|
75
|
+
end,
|
|
76
|
+
debug = function(self, message, data)
|
|
77
|
+
return captureMessageImpl(message, {
|
|
78
|
+
level = "debug",
|
|
79
|
+
context = data,
|
|
80
|
+
})
|
|
81
|
+
end,
|
|
82
|
+
info = function(self, message, data)
|
|
83
|
+
return captureMessageImpl(message, {
|
|
84
|
+
level = "info",
|
|
85
|
+
context = data,
|
|
86
|
+
})
|
|
87
|
+
end,
|
|
88
|
+
warn = function(self, message, data)
|
|
89
|
+
return captureMessageImpl(message, {
|
|
90
|
+
level = "warn",
|
|
91
|
+
context = data,
|
|
92
|
+
})
|
|
93
|
+
end,
|
|
94
|
+
log = function(self, message, data)
|
|
95
|
+
return captureMessageImpl(message, {
|
|
96
|
+
level = "info",
|
|
97
|
+
context = data,
|
|
98
|
+
})
|
|
99
|
+
end,
|
|
100
|
+
setUser = function(self, userId, playerName, data)
|
|
101
|
+
if not initialized then
|
|
102
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
103
|
+
return nil
|
|
104
|
+
end
|
|
105
|
+
scope:setUser(userId, playerName, data)
|
|
106
|
+
end,
|
|
107
|
+
clearUser = function(self)
|
|
108
|
+
if not initialized then
|
|
109
|
+
return nil
|
|
110
|
+
end
|
|
111
|
+
scope:clearUser()
|
|
112
|
+
end,
|
|
113
|
+
addBreadcrumb = function(self, category, message, data)
|
|
114
|
+
if not initialized then
|
|
115
|
+
return nil
|
|
116
|
+
end
|
|
117
|
+
scope:addBreadcrumb(category, message, data)
|
|
118
|
+
end,
|
|
119
|
+
setTag = function(self, key, value)
|
|
120
|
+
if not initialized then
|
|
121
|
+
return nil
|
|
122
|
+
end
|
|
123
|
+
scope:setTag(key, value)
|
|
124
|
+
end,
|
|
125
|
+
setExtra = function(self, key, value)
|
|
126
|
+
if not initialized then
|
|
127
|
+
return nil
|
|
128
|
+
end
|
|
129
|
+
scope:setExtra(key, value)
|
|
130
|
+
end,
|
|
131
|
+
wrap = function(self, fn)
|
|
132
|
+
if not initialized then
|
|
133
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
134
|
+
return fn
|
|
135
|
+
end
|
|
136
|
+
return capture:wrap(fn)
|
|
137
|
+
end,
|
|
138
|
+
withScope = function(self, callback)
|
|
139
|
+
if not initialized then
|
|
140
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
141
|
+
return nil
|
|
142
|
+
end
|
|
143
|
+
local isolatedScope = scope:clone()
|
|
144
|
+
local scopeInterface = {
|
|
145
|
+
setUser = function(userId, playerName, data)
|
|
146
|
+
isolatedScope:setUser(userId, playerName, data)
|
|
147
|
+
end,
|
|
148
|
+
clearUser = function()
|
|
149
|
+
isolatedScope:clearUser()
|
|
150
|
+
end,
|
|
151
|
+
addBreadcrumb = function(category, message, data)
|
|
152
|
+
isolatedScope:addBreadcrumb(category, message, data)
|
|
153
|
+
end,
|
|
154
|
+
setTag = function(key, value)
|
|
155
|
+
isolatedScope:setTag(key, value)
|
|
156
|
+
end,
|
|
157
|
+
setExtra = function(key, value)
|
|
158
|
+
isolatedScope:setExtra(key, value)
|
|
159
|
+
end,
|
|
160
|
+
}
|
|
161
|
+
local originalScope = scope
|
|
162
|
+
scope = isolatedScope
|
|
163
|
+
capture:setScope(isolatedScope)
|
|
164
|
+
traceManager:setScope(isolatedScope)
|
|
165
|
+
local success, err = pcall(function()
|
|
166
|
+
return callback(scopeInterface)
|
|
167
|
+
end)
|
|
168
|
+
scope = originalScope
|
|
169
|
+
capture:setScope(originalScope)
|
|
170
|
+
traceManager:setScope(originalScope)
|
|
171
|
+
if not success then
|
|
172
|
+
capture:captureException(err)
|
|
173
|
+
error(err)
|
|
174
|
+
end
|
|
175
|
+
end,
|
|
176
|
+
flush = function(self)
|
|
177
|
+
if not initialized then
|
|
178
|
+
return nil
|
|
179
|
+
end
|
|
180
|
+
queue:flush()
|
|
181
|
+
end,
|
|
182
|
+
enable = function(self)
|
|
183
|
+
if not initialized then
|
|
184
|
+
return nil
|
|
185
|
+
end
|
|
186
|
+
config:enable()
|
|
187
|
+
debugLog("SDK enabled")
|
|
188
|
+
end,
|
|
189
|
+
disable = function(self)
|
|
190
|
+
if not initialized then
|
|
191
|
+
return nil
|
|
192
|
+
end
|
|
193
|
+
config:disable()
|
|
194
|
+
debugLog("SDK disabled")
|
|
195
|
+
end,
|
|
196
|
+
getStatus = function(self)
|
|
197
|
+
return {
|
|
198
|
+
initialized = initialized,
|
|
199
|
+
enabled = if initialized then config:isEnabled() else false,
|
|
200
|
+
queueSize = if initialized then queue:getSize() else 0,
|
|
201
|
+
}
|
|
202
|
+
end,
|
|
203
|
+
startTrace = function(self, traceName, options)
|
|
204
|
+
if not initialized then
|
|
205
|
+
warn("[RoSentry] SDK not initialized. Call RoSentry.init() first.")
|
|
206
|
+
return nil
|
|
207
|
+
end
|
|
208
|
+
return traceManager:startTrace(traceName, options)
|
|
209
|
+
end,
|
|
210
|
+
getTrace = function(self, traceId)
|
|
211
|
+
if not initialized then
|
|
212
|
+
return nil
|
|
213
|
+
end
|
|
214
|
+
return traceManager:getTrace(traceId)
|
|
215
|
+
end,
|
|
216
|
+
endAllTraces = function(self, status)
|
|
217
|
+
if not initialized then
|
|
218
|
+
return nil
|
|
219
|
+
end
|
|
220
|
+
traceManager:endAllTraces(status)
|
|
221
|
+
end,
|
|
222
|
+
getActiveTraceCount = function(self)
|
|
223
|
+
if not initialized then
|
|
224
|
+
return 0
|
|
225
|
+
end
|
|
226
|
+
return traceManager:getActiveCount()
|
|
227
|
+
end,
|
|
228
|
+
}
|
|
229
|
+
return RoSentry
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Config } from "./Config";
|
|
2
|
+
import { Capture } from "./Capture";
|
|
3
|
+
export declare class AutoCapture {
|
|
4
|
+
private _config;
|
|
5
|
+
private _capture;
|
|
6
|
+
private _connections;
|
|
7
|
+
private _enabled;
|
|
8
|
+
constructor(config: Config, capture: Capture);
|
|
9
|
+
private _debug;
|
|
10
|
+
setup(): void;
|
|
11
|
+
teardown(): void;
|
|
12
|
+
isEnabled(): boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
|
|
4
|
+
local ScriptContext = _services.ScriptContext
|
|
5
|
+
local LogService = _services.LogService
|
|
6
|
+
local AutoCapture
|
|
7
|
+
do
|
|
8
|
+
AutoCapture = setmetatable({}, {
|
|
9
|
+
__tostring = function()
|
|
10
|
+
return "AutoCapture"
|
|
11
|
+
end,
|
|
12
|
+
})
|
|
13
|
+
AutoCapture.__index = AutoCapture
|
|
14
|
+
function AutoCapture.new(...)
|
|
15
|
+
local self = setmetatable({}, AutoCapture)
|
|
16
|
+
return self:constructor(...) or self
|
|
17
|
+
end
|
|
18
|
+
function AutoCapture:constructor(config, capture)
|
|
19
|
+
self._config = config
|
|
20
|
+
self._capture = capture
|
|
21
|
+
self._connections = {}
|
|
22
|
+
self._enabled = false
|
|
23
|
+
end
|
|
24
|
+
function AutoCapture:_debug(...)
|
|
25
|
+
local args = { ... }
|
|
26
|
+
if self._config:get("debug") then
|
|
27
|
+
print("[RoSentry:AutoCapture]", unpack(args))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
function AutoCapture:setup()
|
|
31
|
+
if self._enabled then
|
|
32
|
+
self:_debug("Auto-capture already enabled")
|
|
33
|
+
return nil
|
|
34
|
+
end
|
|
35
|
+
local errorConnection = ScriptContext.Error:Connect(function(message, stackTrace, scriptInstance)
|
|
36
|
+
if not self._config:isEnabled() then
|
|
37
|
+
return nil
|
|
38
|
+
end
|
|
39
|
+
self._capture:captureScriptError(message, stackTrace, scriptInstance)
|
|
40
|
+
end)
|
|
41
|
+
local _exp = self._connections
|
|
42
|
+
table.insert(_exp, errorConnection)
|
|
43
|
+
if self._config:get("captureWarnings") then
|
|
44
|
+
local warningConnection = LogService.MessageOut:Connect(function(message, messageType)
|
|
45
|
+
if not self._config:isEnabled() then
|
|
46
|
+
return nil
|
|
47
|
+
end
|
|
48
|
+
if messageType == Enum.MessageType.MessageWarning then
|
|
49
|
+
self._capture:captureMessage(message, {
|
|
50
|
+
level = "warn",
|
|
51
|
+
})
|
|
52
|
+
end
|
|
53
|
+
end)
|
|
54
|
+
local _exp_1 = self._connections
|
|
55
|
+
table.insert(_exp_1, warningConnection)
|
|
56
|
+
end
|
|
57
|
+
self._enabled = true
|
|
58
|
+
self:_debug("Auto-capture enabled")
|
|
59
|
+
end
|
|
60
|
+
function AutoCapture:teardown()
|
|
61
|
+
for _, connection in self._connections do
|
|
62
|
+
connection:Disconnect()
|
|
63
|
+
end
|
|
64
|
+
self._connections = {}
|
|
65
|
+
self._enabled = false
|
|
66
|
+
self:_debug("Auto-capture disabled")
|
|
67
|
+
end
|
|
68
|
+
function AutoCapture:isEnabled()
|
|
69
|
+
return self._enabled
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
return {
|
|
73
|
+
AutoCapture = AutoCapture,
|
|
74
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CaptureOptions } from "../types";
|
|
2
|
+
import { Config } from "./Config";
|
|
3
|
+
import { Scope } from "./Scope";
|
|
4
|
+
import { Queue } from "./Queue";
|
|
5
|
+
export declare class Capture {
|
|
6
|
+
private _config;
|
|
7
|
+
private _scope;
|
|
8
|
+
private _queue;
|
|
9
|
+
constructor(config: Config, scope: Scope, queue: Queue);
|
|
10
|
+
private _debug;
|
|
11
|
+
private _buildErrorData;
|
|
12
|
+
captureException(err: unknown, options?: CaptureOptions): string | undefined;
|
|
13
|
+
captureMessage(message: string, options?: CaptureOptions): string | undefined;
|
|
14
|
+
captureScriptError(message: string, stackTrace: string, scriptInstance?: Instance): string | undefined;
|
|
15
|
+
wrap(fn: (...args: unknown[]) => unknown): (...args: unknown[]) => unknown;
|
|
16
|
+
setScope(scope: Scope): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _util = TS.import(script, script.Parent, "util")
|
|
4
|
+
local generateUUID = _util.generateUUID
|
|
5
|
+
local getJobId = _util.getJobId
|
|
6
|
+
local getPlaceId = _util.getPlaceId
|
|
7
|
+
local getGameVersion = _util.getGameVersion
|
|
8
|
+
local isServer = _util.isServer
|
|
9
|
+
local sanitizeStackTrace = _util.sanitizeStackTrace
|
|
10
|
+
local getTimestamp = _util.getTimestamp
|
|
11
|
+
local Capture
|
|
12
|
+
do
|
|
13
|
+
Capture = setmetatable({}, {
|
|
14
|
+
__tostring = function()
|
|
15
|
+
return "Capture"
|
|
16
|
+
end,
|
|
17
|
+
})
|
|
18
|
+
Capture.__index = Capture
|
|
19
|
+
function Capture.new(...)
|
|
20
|
+
local self = setmetatable({}, Capture)
|
|
21
|
+
return self:constructor(...) or self
|
|
22
|
+
end
|
|
23
|
+
function Capture:constructor(config, scope, queue)
|
|
24
|
+
self._config = config
|
|
25
|
+
self._scope = scope
|
|
26
|
+
self._queue = queue
|
|
27
|
+
end
|
|
28
|
+
function Capture:_debug(...)
|
|
29
|
+
local args = { ... }
|
|
30
|
+
if self._config:get("debug") then
|
|
31
|
+
print("[RoSentry:Capture]", unpack(args))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
function Capture:_buildErrorData(message, level, stackTrace, options)
|
|
35
|
+
local opts = options or {}
|
|
36
|
+
local user = self._scope:getUser()
|
|
37
|
+
local breadcrumbs = self._scope:getBreadcrumbs()
|
|
38
|
+
local tags = self._scope:getTags()
|
|
39
|
+
local extras = self._scope:getExtras()
|
|
40
|
+
local allTags = {}
|
|
41
|
+
-- ▼ ReadonlyMap.forEach ▼
|
|
42
|
+
local _callback = function(value, key)
|
|
43
|
+
local _arg0 = `{key}:{value}`
|
|
44
|
+
table.insert(allTags, _arg0)
|
|
45
|
+
end
|
|
46
|
+
for _k, _v in tags do
|
|
47
|
+
_callback(_v, _k, tags)
|
|
48
|
+
end
|
|
49
|
+
-- ▲ ReadonlyMap.forEach ▲
|
|
50
|
+
if opts.tags then
|
|
51
|
+
for _, tag in opts.tags do
|
|
52
|
+
table.insert(allTags, tag)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
local errorData = {
|
|
56
|
+
message = message,
|
|
57
|
+
level = opts.level or level,
|
|
58
|
+
stack_trace = sanitizeStackTrace(stackTrace),
|
|
59
|
+
user_id = if user then user.id else nil,
|
|
60
|
+
player_name = if user then user.name else nil,
|
|
61
|
+
job_id = getJobId(),
|
|
62
|
+
place_id = getPlaceId(),
|
|
63
|
+
game_version = getGameVersion(),
|
|
64
|
+
environment = self._config:get("environment"),
|
|
65
|
+
context = {
|
|
66
|
+
userData = if user then user.data else nil,
|
|
67
|
+
custom = opts.context or extras,
|
|
68
|
+
breadcrumbs = breadcrumbs,
|
|
69
|
+
isServer = isServer(),
|
|
70
|
+
script = nil,
|
|
71
|
+
},
|
|
72
|
+
tags = allTags,
|
|
73
|
+
timestamp = getTimestamp(),
|
|
74
|
+
}
|
|
75
|
+
return errorData
|
|
76
|
+
end
|
|
77
|
+
function Capture:captureException(err, options)
|
|
78
|
+
if not self._config:isEnabled() then
|
|
79
|
+
return nil
|
|
80
|
+
end
|
|
81
|
+
local opts = options or {}
|
|
82
|
+
local message = tostring(err)
|
|
83
|
+
local _condition = opts.stackTrace
|
|
84
|
+
if _condition == nil then
|
|
85
|
+
_condition = debug.traceback()
|
|
86
|
+
end
|
|
87
|
+
local stackTrace = _condition
|
|
88
|
+
local errorData = self:_buildErrorData(message, "error", stackTrace, opts)
|
|
89
|
+
local success = self._queue:push(errorData)
|
|
90
|
+
if success then
|
|
91
|
+
self:_debug("Captured exception:", message)
|
|
92
|
+
return generateUUID()
|
|
93
|
+
end
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
function Capture:captureMessage(message, options)
|
|
97
|
+
if not self._config:isEnabled() then
|
|
98
|
+
return nil
|
|
99
|
+
end
|
|
100
|
+
local opts = options or {}
|
|
101
|
+
local level = opts.level or "info"
|
|
102
|
+
local errorData = self:_buildErrorData(message, level, nil, opts)
|
|
103
|
+
local success = self._queue:push(errorData)
|
|
104
|
+
if success then
|
|
105
|
+
self:_debug("Captured message:", message)
|
|
106
|
+
return generateUUID()
|
|
107
|
+
end
|
|
108
|
+
return nil
|
|
109
|
+
end
|
|
110
|
+
function Capture:captureScriptError(message, stackTrace, scriptInstance)
|
|
111
|
+
if not self._config:isEnabled() then
|
|
112
|
+
return nil
|
|
113
|
+
end
|
|
114
|
+
local errorData = self:_buildErrorData(message, "error", stackTrace)
|
|
115
|
+
errorData.context.script = if scriptInstance then scriptInstance:GetFullName() else "Unknown"
|
|
116
|
+
local success = self._queue:push(errorData)
|
|
117
|
+
if success then
|
|
118
|
+
self:_debug("Captured script error:", message)
|
|
119
|
+
return generateUUID()
|
|
120
|
+
end
|
|
121
|
+
return nil
|
|
122
|
+
end
|
|
123
|
+
function Capture:wrap(fn)
|
|
124
|
+
return function(...)
|
|
125
|
+
local args = { ... }
|
|
126
|
+
local success, result = pcall(function()
|
|
127
|
+
return fn(unpack(args))
|
|
128
|
+
end)
|
|
129
|
+
if not success then
|
|
130
|
+
self:captureException(result)
|
|
131
|
+
error(result)
|
|
132
|
+
end
|
|
133
|
+
return result
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
function Capture:setScope(scope)
|
|
137
|
+
self._scope = scope
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
return {
|
|
141
|
+
Capture = Capture,
|
|
142
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Config as ConfigType, ConfigOptions } from "../types";
|
|
2
|
+
export declare class Config {
|
|
3
|
+
private _config;
|
|
4
|
+
constructor();
|
|
5
|
+
init(options: ConfigOptions, isServer: boolean): void;
|
|
6
|
+
get<T extends keyof ConfigType>(key: T): ConfigType[T];
|
|
7
|
+
set<T extends keyof ConfigType>(key: T, value: ConfigType[T]): void;
|
|
8
|
+
getAll(): ConfigType;
|
|
9
|
+
isEnabled(): boolean;
|
|
10
|
+
enable(): void;
|
|
11
|
+
disable(): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local DEFAULT_CONFIG = {
|
|
3
|
+
apiKey = "",
|
|
4
|
+
environment = "production",
|
|
5
|
+
endpoint = "https://rosentry.vercel.app/api/ingest",
|
|
6
|
+
enabled = true,
|
|
7
|
+
sampleRate = 1.0,
|
|
8
|
+
maxBreadcrumbs = 100,
|
|
9
|
+
maxQueueSize = 50,
|
|
10
|
+
flushInterval = 5,
|
|
11
|
+
debug = false,
|
|
12
|
+
autoCapture = true,
|
|
13
|
+
captureWarnings = false,
|
|
14
|
+
beforeSend = nil,
|
|
15
|
+
}
|
|
16
|
+
local Config
|
|
17
|
+
do
|
|
18
|
+
Config = setmetatable({}, {
|
|
19
|
+
__tostring = function()
|
|
20
|
+
return "Config"
|
|
21
|
+
end,
|
|
22
|
+
})
|
|
23
|
+
Config.__index = Config
|
|
24
|
+
function Config.new(...)
|
|
25
|
+
local self = setmetatable({}, Config)
|
|
26
|
+
return self:constructor(...) or self
|
|
27
|
+
end
|
|
28
|
+
function Config:constructor()
|
|
29
|
+
local _object = table.clone(DEFAULT_CONFIG)
|
|
30
|
+
setmetatable(_object, nil)
|
|
31
|
+
self._config = _object
|
|
32
|
+
end
|
|
33
|
+
function Config:init(options, isServer)
|
|
34
|
+
if isServer then
|
|
35
|
+
local _arg0 = options.apiKey ~= nil and options.apiKey ~= ""
|
|
36
|
+
assert(_arg0, "[RoSentry] apiKey is required on server")
|
|
37
|
+
end
|
|
38
|
+
local _condition = options.apiKey
|
|
39
|
+
if _condition == nil then
|
|
40
|
+
_condition = ""
|
|
41
|
+
end
|
|
42
|
+
self._config.apiKey = _condition
|
|
43
|
+
local _condition_1 = options.environment
|
|
44
|
+
if _condition_1 == nil then
|
|
45
|
+
_condition_1 = self._config.environment
|
|
46
|
+
end
|
|
47
|
+
self._config.environment = _condition_1
|
|
48
|
+
local _condition_2 = options.endpoint
|
|
49
|
+
if _condition_2 == nil then
|
|
50
|
+
_condition_2 = self._config.endpoint
|
|
51
|
+
end
|
|
52
|
+
self._config.endpoint = _condition_2
|
|
53
|
+
local _condition_3 = options.enabled
|
|
54
|
+
if _condition_3 == nil then
|
|
55
|
+
_condition_3 = self._config.enabled
|
|
56
|
+
end
|
|
57
|
+
self._config.enabled = _condition_3
|
|
58
|
+
local _condition_4 = options.sampleRate
|
|
59
|
+
if _condition_4 == nil then
|
|
60
|
+
_condition_4 = self._config.sampleRate
|
|
61
|
+
end
|
|
62
|
+
self._config.sampleRate = _condition_4
|
|
63
|
+
local _condition_5 = options.maxBreadcrumbs
|
|
64
|
+
if _condition_5 == nil then
|
|
65
|
+
_condition_5 = self._config.maxBreadcrumbs
|
|
66
|
+
end
|
|
67
|
+
self._config.maxBreadcrumbs = _condition_5
|
|
68
|
+
local _condition_6 = options.maxQueueSize
|
|
69
|
+
if _condition_6 == nil then
|
|
70
|
+
_condition_6 = self._config.maxQueueSize
|
|
71
|
+
end
|
|
72
|
+
self._config.maxQueueSize = _condition_6
|
|
73
|
+
local _condition_7 = options.flushInterval
|
|
74
|
+
if _condition_7 == nil then
|
|
75
|
+
_condition_7 = self._config.flushInterval
|
|
76
|
+
end
|
|
77
|
+
self._config.flushInterval = _condition_7
|
|
78
|
+
local _condition_8 = options.debug
|
|
79
|
+
if _condition_8 == nil then
|
|
80
|
+
_condition_8 = self._config.debug
|
|
81
|
+
end
|
|
82
|
+
self._config.debug = _condition_8
|
|
83
|
+
local _condition_9 = options.autoCapture
|
|
84
|
+
if _condition_9 == nil then
|
|
85
|
+
_condition_9 = self._config.autoCapture
|
|
86
|
+
end
|
|
87
|
+
self._config.autoCapture = _condition_9
|
|
88
|
+
local _condition_10 = options.captureWarnings
|
|
89
|
+
if _condition_10 == nil then
|
|
90
|
+
_condition_10 = self._config.captureWarnings
|
|
91
|
+
end
|
|
92
|
+
self._config.captureWarnings = _condition_10
|
|
93
|
+
self._config.beforeSend = options.beforeSend
|
|
94
|
+
end
|
|
95
|
+
function Config:get(key)
|
|
96
|
+
return self._config[key]
|
|
97
|
+
end
|
|
98
|
+
function Config:set(key, value)
|
|
99
|
+
self._config[key] = value
|
|
100
|
+
end
|
|
101
|
+
function Config:getAll()
|
|
102
|
+
return self._config
|
|
103
|
+
end
|
|
104
|
+
function Config:isEnabled()
|
|
105
|
+
return self._config.enabled
|
|
106
|
+
end
|
|
107
|
+
function Config:enable()
|
|
108
|
+
self._config.enabled = true
|
|
109
|
+
end
|
|
110
|
+
function Config:disable()
|
|
111
|
+
self._config.enabled = false
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
return {
|
|
115
|
+
Config = Config,
|
|
116
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ErrorData } from "../types";
|
|
2
|
+
import { Config } from "./Config";
|
|
3
|
+
import { Transport } from "./Transport";
|
|
4
|
+
export declare class Queue {
|
|
5
|
+
private _config;
|
|
6
|
+
private _transport;
|
|
7
|
+
private _queue;
|
|
8
|
+
private _lastFlush;
|
|
9
|
+
private _flushLoopRunning;
|
|
10
|
+
constructor(config: Config, transport: Transport);
|
|
11
|
+
private _debug;
|
|
12
|
+
private _shouldSample;
|
|
13
|
+
push(errorData: ErrorData): boolean;
|
|
14
|
+
flush(): void;
|
|
15
|
+
startFlushLoop(): void;
|
|
16
|
+
stopFlushLoop(): void;
|
|
17
|
+
getSize(): number;
|
|
18
|
+
clear(): void;
|
|
19
|
+
}
|