Skip to content

Commit c2b9101

Browse files
committed
update actions/core and add error messages
1 parent 5a5e6bd commit c2b9101

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ jobs:
3333
steps:
3434
- uses: actions/checkout@v4
3535

36+
- name: Setup Node.js
37+
uses: actions/setup-node@v4
38+
with:
39+
node-version: '20'
40+
cache: 'npm'
41+
42+
- name: Install dependencies
43+
run: npm ci
44+
45+
- name: Build action
46+
run: npm run build
47+
3648
- name: Test the action
3749
uses: ./
3850
with:

index.js

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,32 @@ async function run() {
88
// Get input parameters
99
const apiKey = core.getInput('launchdarkly_api_key', { required: true });
1010
const projectKey = core.getInput('project_key', { required: true });
11-
const daysAhead = parseInt(core.getInput('days_ahead') || '7', 10);
11+
const daysAheadInput = core.getInput('days_ahead') || '7';
12+
const daysAhead = parseInt(daysAheadInput, 10);
1213
const includePastDue = core.getInput('include_past_due') === 'true';
1314
const customPropertyName = core.getInput('custom_property_name') || 'flag-expiry-date';
1415

16+
// Validate inputs
17+
if (!apiKey.trim()) {
18+
throw new Error('LaunchDarkly API key cannot be empty');
19+
}
20+
if (!projectKey.trim()) {
21+
throw new Error('Project key cannot be empty');
22+
}
23+
if (isNaN(daysAhead) || daysAhead < 0 || daysAhead > 365) {
24+
throw new Error(`Invalid days_ahead value: ${daysAheadInput}. Must be a number between 0 and 365`);
25+
}
26+
if (!customPropertyName.trim()) {
27+
throw new Error('Custom property name cannot be empty');
28+
}
29+
1530
core.info(`Starting LaunchDarkly flag expiry audit for project: ${projectKey}`);
1631
core.info(`Looking for flags expiring within ${daysAhead} days`);
1732
core.info(`Include past due flags: ${includePastDue}`);
1833
core.info(`Custom property name: ${customPropertyName}`);
34+
35+
core.debug(`Input validation completed successfully`);
36+
core.debug(`API key length: ${apiKey.length} characters`);
1937

2038
// Get all feature flags for the project
2139
const flags = await getAllFeatureFlags(apiKey, projectKey);
@@ -113,7 +131,16 @@ async function run() {
113131
await core.summary.write();
114132

115133
} catch (error) {
116-
core.setFailed(`Action failed with error: ${error.message}`);
134+
core.error('Action execution failed', error);
135+
136+
// Provide specific error context based on error type
137+
if (error.message.includes('LaunchDarkly API request failed')) {
138+
core.setFailed(`LaunchDarkly API Error: ${error.message}`);
139+
} else if (error.message.includes('MODULE_NOT_FOUND')) {
140+
core.setFailed(`Dependency Error: ${error.message}`);
141+
} else {
142+
core.setFailed(`Action failed with error: ${error.message}`);
143+
}
117144
}
118145
}
119146

@@ -129,6 +156,7 @@ async function getAllFeatureFlags(apiKey, projectKey) {
129156
while (true) {
130157
const url = `https://app.launchdarkly.com/api/v2/flags/${projectKey}?limit=${limit}&offset=${offset}`;
131158

159+
core.debug(`Fetching flags: offset=${offset}, limit=${limit}`);
132160
const response = await fetch(url, {
133161
headers: {
134162
'Authorization': apiKey,
@@ -137,7 +165,18 @@ async function getAllFeatureFlags(apiKey, projectKey) {
137165
});
138166

139167
if (!response.ok) {
140-
throw new Error(`LaunchDarkly API request failed: ${response.status} ${response.statusText}`);
168+
let errorMessage = `LaunchDarkly API request failed: ${response.status} ${response.statusText}`;
169+
170+
// Provide specific guidance for common errors
171+
if (response.status === 401) {
172+
errorMessage += '. Please check your API key is valid and has the required permissions.';
173+
} else if (response.status === 404) {
174+
errorMessage += `. Project '${projectKey}' may not exist or you don't have access to it.`;
175+
} else if (response.status === 429) {
176+
errorMessage += '. Rate limit exceeded. Please wait and try again.';
177+
}
178+
179+
throw new Error(errorMessage);
141180
}
142181

143182
const data = await response.json();
@@ -146,11 +185,15 @@ async function getAllFeatureFlags(apiKey, projectKey) {
146185
flags.push(...data.items);
147186
offset += limit;
148187

188+
core.debug(`Retrieved ${data.items.length} flags (total so far: ${flags.length})`);
189+
149190
// If we got fewer items than the limit, we've reached the end
150191
if (data.items.length < limit) {
192+
core.debug(`Reached end of results (got ${data.items.length} < ${limit})`);
151193
break;
152194
}
153195
} else {
196+
core.debug('No items returned, ending pagination');
154197
break;
155198
}
156199
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
],
1919
"license": "MIT",
2020
"dependencies": {
21-
"@actions/core": "^1.10.1",
21+
"@actions/core": "^1.11.1",
2222
"@actions/github": "^6.0.0",
2323
"node-fetch": "^2.7.0"
2424
},

0 commit comments

Comments
 (0)