erlc-api 3.0.0 → 3.2.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/README.md +86 -17
- package/examples/error-handling.js +159 -0
- package/package.json +1 -1
- package/src/classes/client.js +23 -20
- package/src/erlc.js +1 -0
- package/src/errors/ErlcError.js +34 -0
- package/src/errors/errorCodes.js +218 -0
- package/src/functions/global/resetGlobalKey.js +60 -0
- package/src/functions/server/getBans.js +17 -18
- package/src/functions/server/getCommandLogs.js +17 -18
- package/src/functions/server/getJoinLogs.js +17 -18
- package/src/functions/server/getKillLogs.js +17 -18
- package/src/functions/server/getModcallLogs.js +17 -18
- package/src/functions/server/getPlayers.js +17 -18
- package/src/functions/server/getQueue.js +17 -18
- package/src/functions/server/getServer.js +46 -19
- package/src/functions/server/getStaff.js +17 -18
- package/src/functions/server/getVehicles.js +17 -18
- package/src/functions/server/runCommand.js +20 -23
- package/src/types/index.d.ts +127 -98
- package/src/utils/errorHandler.js +158 -0
package/README.md
CHANGED
|
@@ -292,17 +292,37 @@ const handleApiCall = async () => {
|
|
|
292
292
|
const result = await erlc.getServer(serverToken);
|
|
293
293
|
return result;
|
|
294
294
|
} catch (error) {
|
|
295
|
-
//
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
295
|
+
// The error is now an ErlcError with detailed information
|
|
296
|
+
console.error(`Error ${error.code}: ${error.message}`);
|
|
297
|
+
console.error(`Category: ${error.category}, Severity: ${error.severity}`);
|
|
298
|
+
|
|
299
|
+
// Handle specific ERLC error codes
|
|
300
|
+
switch (error.code) {
|
|
301
|
+
case 2002:
|
|
302
|
+
console.error(
|
|
303
|
+
"Invalid server key - get a new one from server settings"
|
|
304
|
+
);
|
|
305
|
+
break;
|
|
306
|
+
case 4001:
|
|
307
|
+
console.error("Rate limited - reduce request frequency");
|
|
308
|
+
break;
|
|
309
|
+
case 3002:
|
|
310
|
+
console.error("Server offline - wait for players to join");
|
|
311
|
+
break;
|
|
312
|
+
case 9999:
|
|
313
|
+
console.error("Server module outdated - restart server");
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Show suggested actions
|
|
318
|
+
if (error.suggestions) {
|
|
319
|
+
console.error("Suggested actions:");
|
|
320
|
+
error.suggestions.forEach((action) => console.error(`- ${action}`));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Check if error is retryable
|
|
324
|
+
if (error.retryable) {
|
|
325
|
+
console.error("This error might be resolved by retrying");
|
|
306
326
|
}
|
|
307
327
|
|
|
308
328
|
throw error; // Re-throw if needed
|
|
@@ -386,13 +406,62 @@ const joinLogs: JoinLog[] = await erlc.getJoinLogs(serverToken);
|
|
|
386
406
|
|
|
387
407
|
## 🐛 Error Types
|
|
388
408
|
|
|
389
|
-
The wrapper provides
|
|
409
|
+
The wrapper provides comprehensive error handling with specific ERLC error codes:
|
|
410
|
+
|
|
411
|
+
### ERLC Error Codes
|
|
412
|
+
|
|
413
|
+
| Code | Category | Description |
|
|
414
|
+
| ---- | -------------------- | -------------------------------------- |
|
|
415
|
+
| 0 | System Error | Unknown error occurred |
|
|
416
|
+
| 1001 | Communication Error | Error communicating with Roblox server |
|
|
417
|
+
| 1002 | System Error | Internal system error |
|
|
418
|
+
| 2000 | Authentication Error | Missing server key |
|
|
419
|
+
| 2001 | Authentication Error | Invalid server key format |
|
|
420
|
+
| 2002 | Authentication Error | Invalid or expired server key |
|
|
421
|
+
| 2003 | Authentication Error | Invalid global API key |
|
|
422
|
+
| 2004 | Authentication Error | Server key banned |
|
|
423
|
+
| 3001 | Request Error | Invalid command provided |
|
|
424
|
+
| 3002 | Request Error | Server offline (no players) |
|
|
425
|
+
| 4001 | Rate Limit Error | Rate limited |
|
|
426
|
+
| 4002 | Permission Error | Restricted command |
|
|
427
|
+
| 4003 | Content Error | Prohibited message |
|
|
428
|
+
| 9998 | Access Error | Restricted resource |
|
|
429
|
+
| 9999 | Version Error | Outdated server module |
|
|
430
|
+
|
|
431
|
+
### Error Properties
|
|
432
|
+
|
|
433
|
+
All errors are instances of `ErlcError` with these properties:
|
|
434
|
+
|
|
435
|
+
- `code`: ERLC error code or HTTP status
|
|
436
|
+
- `message`: Human-readable error message
|
|
437
|
+
- `category`: Error category (e.g., "AUTHENTICATION_ERROR")
|
|
438
|
+
- `severity`: Error severity ("LOW", "MEDIUM", "HIGH", "CRITICAL")
|
|
439
|
+
- `suggestions`: Array of suggested actions to resolve the error
|
|
440
|
+
- `retryable`: Boolean indicating if the error might be resolved by retrying
|
|
441
|
+
- `timestamp`: ISO timestamp when the error occurred
|
|
442
|
+
|
|
443
|
+
### Retry Logic Example
|
|
390
444
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
445
|
+
```javascript
|
|
446
|
+
async function withRetry(apiCall, maxRetries = 3) {
|
|
447
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
448
|
+
try {
|
|
449
|
+
return await apiCall();
|
|
450
|
+
} catch (error) {
|
|
451
|
+
if (!error.retryable || attempt === maxRetries) {
|
|
452
|
+
throw error;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Wait before retrying with exponential backoff
|
|
456
|
+
const delay = 1000 * Math.pow(2, attempt - 1);
|
|
457
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Usage
|
|
463
|
+
const players = await withRetry(() => erlc.getPlayers(serverToken));
|
|
464
|
+
```
|
|
396
465
|
|
|
397
466
|
## 🤝 Contributing
|
|
398
467
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
const erlc = require("../index.js");
|
|
2
|
+
|
|
3
|
+
// Initialize the client
|
|
4
|
+
const client = new erlc.Client({
|
|
5
|
+
globalToken: "your-global-token-here",
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
client.config();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Example of comprehensive error handling with the new ERLC error system
|
|
12
|
+
*/
|
|
13
|
+
async function demonstrateErrorHandling() {
|
|
14
|
+
const serverToken = "your-server-token-here";
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// This might fail with various ERLC error codes
|
|
18
|
+
const serverInfo = await erlc.getServer(serverToken);
|
|
19
|
+
console.log("✅ Server info retrieved successfully:", serverInfo.Name);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
// The error is now an ErlcError instance with detailed information
|
|
22
|
+
console.error("❌ Error occurred:");
|
|
23
|
+
console.error(`Code: ${error.code}`);
|
|
24
|
+
console.error(`Message: ${error.message}`);
|
|
25
|
+
console.error(`Category: ${error.category}`);
|
|
26
|
+
console.error(`Severity: ${error.severity}`);
|
|
27
|
+
|
|
28
|
+
if (error.suggestions) {
|
|
29
|
+
console.error("💡 Suggested actions:");
|
|
30
|
+
error.suggestions.forEach((suggestion, index) => {
|
|
31
|
+
console.error(` ${index + 1}. ${suggestion}`);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (error.retryable) {
|
|
36
|
+
console.error("🔄 This error might be resolved by retrying");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Handle specific error codes
|
|
40
|
+
switch (error.code) {
|
|
41
|
+
case 2002:
|
|
42
|
+
console.error(
|
|
43
|
+
"🔑 Your server key is invalid or expired. Please get a new one from your server settings."
|
|
44
|
+
);
|
|
45
|
+
break;
|
|
46
|
+
case 4001:
|
|
47
|
+
console.error(
|
|
48
|
+
"⏱️ You're being rate limited. Waiting 60 seconds before retry..."
|
|
49
|
+
);
|
|
50
|
+
// Implement retry logic here
|
|
51
|
+
break;
|
|
52
|
+
case 3002:
|
|
53
|
+
console.error(
|
|
54
|
+
"🏃 Server is offline (no players). Waiting for players to join..."
|
|
55
|
+
);
|
|
56
|
+
break;
|
|
57
|
+
case 9999:
|
|
58
|
+
console.error(
|
|
59
|
+
"🔄 Server module is outdated. Please kick all players and restart the server."
|
|
60
|
+
);
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
console.error("🤔 Unexpected error occurred");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Example of handling multiple API calls with proper error handling
|
|
70
|
+
*/
|
|
71
|
+
async function handleMultipleApiCalls() {
|
|
72
|
+
const serverToken = "your-server-token-here";
|
|
73
|
+
|
|
74
|
+
const apiCalls = [
|
|
75
|
+
{ name: "Server Info", call: () => erlc.getServer(serverToken) },
|
|
76
|
+
{ name: "Players", call: () => erlc.getPlayers(serverToken) },
|
|
77
|
+
{ name: "Staff", call: () => erlc.getStaff(serverToken) },
|
|
78
|
+
{ name: "Vehicles", call: () => erlc.getVehicles(serverToken) },
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
for (const { name, call } of apiCalls) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await call();
|
|
84
|
+
console.log(`✅ ${name}: Success`);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`❌ ${name}: Failed`);
|
|
87
|
+
console.error(` Code: ${error.code}`);
|
|
88
|
+
console.error(` Message: ${error.message}`);
|
|
89
|
+
|
|
90
|
+
// Skip retryable errors for this example
|
|
91
|
+
if (!error.retryable) {
|
|
92
|
+
console.error(` This is a non-retryable error, stopping execution`);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Example of implementing retry logic for retryable errors
|
|
101
|
+
*/
|
|
102
|
+
async function withRetry(apiCall, maxRetries = 3, delayMs = 1000) {
|
|
103
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
104
|
+
try {
|
|
105
|
+
return await apiCall();
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(`Attempt ${attempt} failed:`, error.message);
|
|
108
|
+
|
|
109
|
+
if (!error.retryable || attempt === maxRetries) {
|
|
110
|
+
throw error; // Don't retry non-retryable errors or if max retries reached
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Wait before retrying (exponential backoff)
|
|
114
|
+
const delay = delayMs * Math.pow(2, attempt - 1);
|
|
115
|
+
console.log(`Waiting ${delay}ms before retry...`);
|
|
116
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Example usage of retry logic
|
|
123
|
+
*/
|
|
124
|
+
async function demonstrateRetryLogic() {
|
|
125
|
+
const serverToken = "your-server-token-here";
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const players = await withRetry(() => erlc.getPlayers(serverToken));
|
|
129
|
+
console.log("✅ Players retrieved successfully:", players.length);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error("❌ Failed after all retries:", error.message);
|
|
132
|
+
|
|
133
|
+
if (error.suggestions) {
|
|
134
|
+
console.error("💡 Try these suggestions:");
|
|
135
|
+
error.suggestions.forEach((suggestion) =>
|
|
136
|
+
console.error(` - ${suggestion}`)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Run examples
|
|
143
|
+
if (require.main === module) {
|
|
144
|
+
console.log("🚀 ERLC API Error Handling Examples\n");
|
|
145
|
+
|
|
146
|
+
demonstrateErrorHandling()
|
|
147
|
+
.then(() => console.log("\n" + "=".repeat(50) + "\n"))
|
|
148
|
+
.then(() => handleMultipleApiCalls())
|
|
149
|
+
.then(() => console.log("\n" + "=".repeat(50) + "\n"))
|
|
150
|
+
.then(() => demonstrateRetryLogic())
|
|
151
|
+
.catch(console.error);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = {
|
|
155
|
+
demonstrateErrorHandling,
|
|
156
|
+
handleMultipleApiCalls,
|
|
157
|
+
withRetry,
|
|
158
|
+
demonstrateRetryLogic,
|
|
159
|
+
};
|
package/package.json
CHANGED
package/src/classes/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const erlc = require(
|
|
2
|
-
const assert = require(
|
|
1
|
+
const erlc = require("../erlc.js");
|
|
2
|
+
const assert = require("../functions/assert.js");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @typedef {Object} ClientConfig
|
|
@@ -13,24 +13,27 @@ const assert = require('../functions/assert.js')
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
class Client {
|
|
16
|
+
/**
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {ClientConfig} options - Client Options
|
|
19
|
+
*/
|
|
20
|
+
constructor(options) {
|
|
21
|
+
assert(
|
|
22
|
+
typeof options === "object",
|
|
23
|
+
`Syntax error: object expected for "options", received ${typeof options}`,
|
|
24
|
+
);
|
|
25
|
+
this.options = { ...options };
|
|
26
|
+
this.config();
|
|
27
|
+
}
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Updates and returns the client configurationg
|
|
28
|
-
* @returns {ClientConfig} The client configuration.
|
|
29
|
-
*/
|
|
30
|
-
config() {
|
|
31
|
-
erlc.config = this.options
|
|
32
|
-
return erlc.config
|
|
33
|
-
}
|
|
29
|
+
/**
|
|
30
|
+
* Updates and returns the client configurationg
|
|
31
|
+
* @returns {ClientConfig} The client configuration.
|
|
32
|
+
*/
|
|
33
|
+
config() {
|
|
34
|
+
erlc.config = this.options;
|
|
35
|
+
return erlc.config;
|
|
36
|
+
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
module.exports = Client
|
|
39
|
+
module.exports = Client;
|
package/src/erlc.js
CHANGED
|
@@ -11,5 +11,6 @@ exports.getQueue = require("./functions/server/getQueue.js");
|
|
|
11
11
|
exports.runCommand = require("./functions/server/runCommand.js");
|
|
12
12
|
exports.getVehicles = require("./functions/server/getVehicles.js");
|
|
13
13
|
exports.getStaff = require("./functions/server/getStaff.js");
|
|
14
|
+
exports.resetGlobalKey = require("./functions/global/resetGlobalKey.js");
|
|
14
15
|
|
|
15
16
|
exports.Client = require("./classes/client.js");
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class ErlcError extends Error {
|
|
2
|
+
constructor(message, code, status, originalError = null) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "ErlcError";
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.originalError = originalError;
|
|
8
|
+
this.timestamp = new Date().toISOString();
|
|
9
|
+
|
|
10
|
+
if (Error.captureStackTrace) {
|
|
11
|
+
Error.captureStackTrace(this, ErlcError);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Returns a JSON representation of the error
|
|
17
|
+
*/
|
|
18
|
+
toJSON() {
|
|
19
|
+
return {
|
|
20
|
+
name: this.name,
|
|
21
|
+
message: this.message,
|
|
22
|
+
code: this.code,
|
|
23
|
+
status: this.status,
|
|
24
|
+
timestamp: this.timestamp,
|
|
25
|
+
stack: this.stack,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toString() {
|
|
30
|
+
return `${this.name} [${this.code}]: ${this.message}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = ErlcError;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
const ERLC_ERROR_CODES = {
|
|
2
|
+
// System Errors (0-999)
|
|
3
|
+
0: {
|
|
4
|
+
message: "Unknown error occurred",
|
|
5
|
+
description:
|
|
6
|
+
"An unexpected error happened. If this persists, contact PRC via an API ticket.",
|
|
7
|
+
category: "SYSTEM_ERROR",
|
|
8
|
+
severity: "HIGH",
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// Communication Errors (1000-1999)
|
|
12
|
+
1001: {
|
|
13
|
+
message: "Communication error with Roblox server",
|
|
14
|
+
description:
|
|
15
|
+
"Failed to communicate with Roblox or the in-game private server. The server may be experiencing issues.",
|
|
16
|
+
category: "COMMUNICATION_ERROR",
|
|
17
|
+
severity: "HIGH",
|
|
18
|
+
},
|
|
19
|
+
1002: {
|
|
20
|
+
message: "Internal system error",
|
|
21
|
+
description: "An internal system error occurred on the ERLC API servers.",
|
|
22
|
+
category: "SYSTEM_ERROR",
|
|
23
|
+
severity: "HIGH",
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Authentication Errors (2000-2999)
|
|
27
|
+
2000: {
|
|
28
|
+
message: "Missing server key",
|
|
29
|
+
description: "You must provide a valid server-key header in your request.",
|
|
30
|
+
category: "AUTHENTICATION_ERROR",
|
|
31
|
+
severity: "HIGH",
|
|
32
|
+
},
|
|
33
|
+
2001: {
|
|
34
|
+
message: "Invalid server key format",
|
|
35
|
+
description: "The server-key you provided is incorrectly formatted.",
|
|
36
|
+
category: "AUTHENTICATION_ERROR",
|
|
37
|
+
severity: "HIGH",
|
|
38
|
+
},
|
|
39
|
+
2002: {
|
|
40
|
+
message: "Invalid or expired server key",
|
|
41
|
+
description:
|
|
42
|
+
"The server-key you provided is invalid or has expired. Please check your server settings.",
|
|
43
|
+
category: "AUTHENTICATION_ERROR",
|
|
44
|
+
severity: "HIGH",
|
|
45
|
+
},
|
|
46
|
+
2003: {
|
|
47
|
+
message: "Invalid global API key",
|
|
48
|
+
description:
|
|
49
|
+
"The global API key you provided is invalid. Please check your client configuration.",
|
|
50
|
+
category: "AUTHENTICATION_ERROR",
|
|
51
|
+
severity: "HIGH",
|
|
52
|
+
},
|
|
53
|
+
2004: {
|
|
54
|
+
message: "Server key banned",
|
|
55
|
+
description:
|
|
56
|
+
"Your server-key has been banned from accessing the API. Contact PRC support for assistance.",
|
|
57
|
+
category: "AUTHENTICATION_ERROR",
|
|
58
|
+
severity: "CRITICAL",
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Request Errors (3000-3999)
|
|
62
|
+
3001: {
|
|
63
|
+
message: "Invalid command provided",
|
|
64
|
+
description: "You must provide a valid command in the request body.",
|
|
65
|
+
category: "REQUEST_ERROR",
|
|
66
|
+
severity: "MEDIUM",
|
|
67
|
+
},
|
|
68
|
+
3002: {
|
|
69
|
+
message: "Server offline",
|
|
70
|
+
description:
|
|
71
|
+
"The server you are trying to reach is currently offline (has no players).",
|
|
72
|
+
category: "REQUEST_ERROR",
|
|
73
|
+
severity: "MEDIUM",
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Rate Limiting & Restrictions (4000-4999)
|
|
77
|
+
4001: {
|
|
78
|
+
message: "Rate limited",
|
|
79
|
+
description:
|
|
80
|
+
"You are being rate limited. Please reduce your request frequency and try again later.",
|
|
81
|
+
category: "RATE_LIMIT_ERROR",
|
|
82
|
+
severity: "MEDIUM",
|
|
83
|
+
},
|
|
84
|
+
4002: {
|
|
85
|
+
message: "Restricted command",
|
|
86
|
+
description:
|
|
87
|
+
"The command you are attempting to run is restricted and cannot be executed.",
|
|
88
|
+
category: "PERMISSION_ERROR",
|
|
89
|
+
severity: "MEDIUM",
|
|
90
|
+
},
|
|
91
|
+
4003: {
|
|
92
|
+
message: "Prohibited message",
|
|
93
|
+
description:
|
|
94
|
+
"The message you're trying to send contains prohibited content.",
|
|
95
|
+
category: "CONTENT_ERROR",
|
|
96
|
+
severity: "MEDIUM",
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// Access Errors (9000-9999)
|
|
100
|
+
9998: {
|
|
101
|
+
message: "Restricted resource",
|
|
102
|
+
description: "The resource you are trying to access is restricted.",
|
|
103
|
+
category: "ACCESS_ERROR",
|
|
104
|
+
severity: "HIGH",
|
|
105
|
+
},
|
|
106
|
+
9999: {
|
|
107
|
+
message: "Outdated server module",
|
|
108
|
+
description:
|
|
109
|
+
"The module running on the in-game server is out of date. Please kick all players and try again.",
|
|
110
|
+
category: "VERSION_ERROR",
|
|
111
|
+
severity: "HIGH",
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Gets error information by code
|
|
117
|
+
* @param {number} code - The ERLC error code
|
|
118
|
+
* @returns {Object} Error information object
|
|
119
|
+
*/
|
|
120
|
+
function getErrorInfo(code) {
|
|
121
|
+
const errorInfo = ERLC_ERROR_CODES[code];
|
|
122
|
+
if (!errorInfo) {
|
|
123
|
+
return {
|
|
124
|
+
message: `Unknown ERLC error code: ${code}`,
|
|
125
|
+
description:
|
|
126
|
+
"This error code is not recognized. Please check the ERLC API documentation.",
|
|
127
|
+
category: "UNKNOWN_ERROR",
|
|
128
|
+
severity: "MEDIUM",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { ...errorInfo, code };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Checks if an error code indicates a retryable error
|
|
136
|
+
* @param {number} code - The ERLC error code
|
|
137
|
+
* @returns {boolean} True if the error might be resolved by retrying
|
|
138
|
+
*/
|
|
139
|
+
function isRetryableError(code) {
|
|
140
|
+
const retryableCodes = [1001, 1002, 4001]; // Communication errors and rate limits
|
|
141
|
+
return retryableCodes.includes(code);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Checks if an error code indicates an authentication issue
|
|
146
|
+
* @param {number} code - The ERLC error code
|
|
147
|
+
* @returns {boolean} True if the error is authentication-related
|
|
148
|
+
*/
|
|
149
|
+
function isAuthenticationError(code) {
|
|
150
|
+
return code >= 2000 && code <= 2999;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Gets suggested actions for an error code
|
|
155
|
+
* @param {number} code - The ERLC error code
|
|
156
|
+
* @returns {string[]} Array of suggested actions
|
|
157
|
+
*/
|
|
158
|
+
function getSuggestedActions(code) {
|
|
159
|
+
const actions = {
|
|
160
|
+
0: [
|
|
161
|
+
"Contact PRC support via API ticket",
|
|
162
|
+
"Check server logs for more details",
|
|
163
|
+
],
|
|
164
|
+
1001: [
|
|
165
|
+
"Check server status",
|
|
166
|
+
"Verify server is online",
|
|
167
|
+
"Try again in a few minutes",
|
|
168
|
+
],
|
|
169
|
+
1002: ["Try again later", "Contact PRC support if issue persists"],
|
|
170
|
+
2000: [
|
|
171
|
+
"Add server-key header to your request",
|
|
172
|
+
"Check API integration code",
|
|
173
|
+
],
|
|
174
|
+
2001: [
|
|
175
|
+
"Verify server-key format",
|
|
176
|
+
"Get new server-key from server settings",
|
|
177
|
+
],
|
|
178
|
+
2002: [
|
|
179
|
+
"Get new server-key from server settings",
|
|
180
|
+
"Verify server is still active",
|
|
181
|
+
],
|
|
182
|
+
2003: [
|
|
183
|
+
"Check global API token configuration",
|
|
184
|
+
"Verify client initialization",
|
|
185
|
+
],
|
|
186
|
+
2004: ["Contact PRC support immediately", "Review API usage policies"],
|
|
187
|
+
3001: ["Check command format", "Ensure command is not empty"],
|
|
188
|
+
3002: ["Wait for players to join server", "Check server status"],
|
|
189
|
+
4001: [
|
|
190
|
+
"Reduce request frequency",
|
|
191
|
+
"Implement rate limiting in your code",
|
|
192
|
+
"Wait before retrying",
|
|
193
|
+
],
|
|
194
|
+
4002: ["Use a different command", "Check command permissions"],
|
|
195
|
+
4003: ["Review message content", "Remove prohibited words or phrases"],
|
|
196
|
+
9998: ["Check API permissions", "Contact server administrator"],
|
|
197
|
+
9999: [
|
|
198
|
+
"Kick all players from server",
|
|
199
|
+
"Restart server",
|
|
200
|
+
"Update server module",
|
|
201
|
+
],
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
actions[code] || [
|
|
206
|
+
"Check ERLC API documentation",
|
|
207
|
+
"Contact PRC support if needed",
|
|
208
|
+
]
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
module.exports = {
|
|
213
|
+
ERLC_ERROR_CODES,
|
|
214
|
+
getErrorInfo,
|
|
215
|
+
isRetryableError,
|
|
216
|
+
isAuthenticationError,
|
|
217
|
+
getSuggestedActions,
|
|
218
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const { BASEURL } = require("../../constants.js");
|
|
2
|
+
const { processError } = require("../../utils/errorHandler.js");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resets the global API key
|
|
6
|
+
* @returns {Promise<string>} Promise that resolves to the new global API key
|
|
7
|
+
*/
|
|
8
|
+
module.exports = () => {
|
|
9
|
+
return new Promise(async (resolve, reject) => {
|
|
10
|
+
try {
|
|
11
|
+
const fetch = await import("node-fetch");
|
|
12
|
+
const { config } = await import("../../erlc.js");
|
|
13
|
+
|
|
14
|
+
// Check if global token is configured
|
|
15
|
+
if (!config?.globalToken) {
|
|
16
|
+
const error = await processError(
|
|
17
|
+
new Error(
|
|
18
|
+
"Global token not configured. Please initialize the client first.",
|
|
19
|
+
),
|
|
20
|
+
);
|
|
21
|
+
return reject(error);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const res = await fetch.default(`${BASEURL}/api-key/reset`, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: config.globalToken,
|
|
28
|
+
},
|
|
29
|
+
timeout: 10000, // 10 second timeout
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
const errorData = await res
|
|
34
|
+
.json()
|
|
35
|
+
.catch(() => ({ error: "Unknown API error" }));
|
|
36
|
+
const error = await processError(res, errorData);
|
|
37
|
+
return reject(error);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The response is likely a JSON with the new key, or just the key string?
|
|
41
|
+
// Docs say: "This will send a new key which can only be viewed once."
|
|
42
|
+
// Let's assume it returns a JSON object or just the string.
|
|
43
|
+
// Usually these APIs return a JSON object like { "key": "..." } or similar.
|
|
44
|
+
// However, looking at other endpoints, they return data directly.
|
|
45
|
+
// Let's assume it returns a JSON with the key, or we can inspect the response content type.
|
|
46
|
+
// But for now, let's try to parse as JSON.
|
|
47
|
+
|
|
48
|
+
const data = await res.json();
|
|
49
|
+
// If data has a specific field for the key, we should return that.
|
|
50
|
+
// If the documentation doesn't specify, I'll return the whole data object or try to find the key.
|
|
51
|
+
// Based on "This will send a new key", it might be { "apiKey": "..." } or just the string if it's text/plain.
|
|
52
|
+
// Given other endpoints return JSON, this likely returns JSON.
|
|
53
|
+
|
|
54
|
+
resolve(data);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
const processedError = await processError(error);
|
|
57
|
+
reject(processedError);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|