Skip to content

Commit ebe1490

Browse files
authored
fix(uniq): Handle non-array cases (#94354)
Fixes #93417.
1 parent f922376 commit ebe1490

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

static/app/components/events/interfaces/frame/stacktraceLinkModal.spec.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,33 @@ describe('StacktraceLinkModal', () => {
222222
})
223223
);
224224
});
225+
226+
it('displays nothing for null body', async () => {
227+
MockApiClient.addMockResponse({
228+
url: `/organizations/${org.slug}/derive-code-mappings/`,
229+
body: {},
230+
});
231+
232+
renderGlobalModal();
233+
act(() =>
234+
openModal(modalProps => (
235+
<StacktraceLinkModal
236+
{...modalProps}
237+
filename={filename}
238+
closeModal={closeModal}
239+
integrations={[integration]}
240+
organization={org}
241+
project={project}
242+
onSubmit={onSubmit}
243+
/>
244+
))
245+
);
246+
247+
// Wait for component to render, then check that suggestions text is not present
248+
await waitFor(() => {
249+
expect(
250+
screen.queryByText('Select from one of these suggestions or paste your URL below')
251+
).not.toBeInTheDocument();
252+
});
253+
});
225254
});

static/app/components/events/interfaces/frame/stacktraceLinkModal.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function StacktraceLinkModal({
5959
const [error, setError] = useState<null | string>(null);
6060
const [sourceCodeInput, setSourceCodeInput] = useState('');
6161

62-
const {data: suggestedCodeMappings} = useApiQuery<DerivedCodeMapping[]>(
62+
const {data: suggestedCodeMappings} = useApiQuery<DerivedCodeMapping[] | null>(
6363
[
6464
`/organizations/${organization.slug}/derive-code-mappings/`,
6565
{
@@ -81,9 +81,11 @@ function StacktraceLinkModal({
8181
);
8282

8383
const suggestions = uniq(
84-
suggestedCodeMappings?.map(suggestion => {
85-
return `https://github.com/${suggestion.repo_name}/blob/${suggestion.repo_branch}/${suggestion.filename}`;
86-
})
84+
Array.isArray(suggestedCodeMappings)
85+
? suggestedCodeMappings.map(suggestion => {
86+
return `https://github.com/${suggestion.repo_name}/blob/${suggestion.repo_branch}/${suggestion.filename}`;
87+
})
88+
: []
8789
).slice(0, 2);
8890

8991
const onHandleChange = (input: string) => {

static/app/utils/array/uniq.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,24 @@ describe('uniq', () => {
88
it('should return empty array for undefined input', () => {
99
expect(uniq(undefined)).toStrictEqual([]);
1010
});
11+
12+
it('should return empty array for null input', () => {
13+
expect(uniq(null)).toStrictEqual([]);
14+
});
15+
16+
it('should return empty array for empty object input', () => {
17+
expect(uniq({} as any)).toStrictEqual([]);
18+
});
19+
20+
it('should return empty array for non-array objects', () => {
21+
expect(uniq({key: 'value'} as any)).toStrictEqual([]);
22+
});
23+
24+
it('should return empty array for string input', () => {
25+
expect(uniq('string' as any)).toStrictEqual([]);
26+
});
27+
28+
it('should return empty array for number input', () => {
29+
expect(uniq(123 as any)).toStrictEqual([]);
30+
});
1131
});

static/app/utils/array/uniq.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/**
22
* Returns unique values of the given array.
33
*/
4-
export function uniq<T = unknown>(items: T[] | undefined): T[] {
4+
export function uniq<T = unknown>(items: T[] | undefined | null): T[] {
5+
if (!Array.isArray(items)) {
6+
return [];
7+
}
58
return [...new Set(items)];
69
}

0 commit comments

Comments
 (0)