Skip to content

Commit a6c7695

Browse files
fix(web): return graceful error for unknown search context (#1362)
* fix(web): return graceful error for unknown search context context:<value> resolves a named search context. When the context did not exist, onExpandSearchContext threw a plain Error, which is not caught by the SyntaxError-only handler and crashed the request. Throw a ServiceErrorException with SEARCH_CONTEXT_NOT_FOUND so it returns a clean 404 instead. Fixes #1312 * docs: add changelog entry for search context crash fix * Fix changelog --------- Co-authored-by: Brendan Kellam <brendan@sourcebot.dev>
1 parent b7c3158 commit a6c7695

3 files changed

Lines changed: 51 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Upgraded `brace-expansion` to `^1.1.17`/`^2.1.3`/`^5.0.8`. [#1527](https://github.com/sourcebot-dev/sourcebot/pull/1527)
1212
- Upgraded `tar` to `^7.5.22`. [#1472](https://github.com/sourcebot-dev/sourcebot/pull/1472)
1313
- Fixed GitLab topic filters being incorrectly case-sensitive. [#1393](https://github.com/sourcebot-dev/sourcebot/pull/1393)
14+
- Fixed a crash when searching with `context:` referencing a search context that does not exist; it now returns a graceful error. [#1362](https://github.com/sourcebot-dev/sourcebot/pull/1362)
1415

1516
## [5.1.5] - 2026-07-31
1617

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { describe, expect, it } from 'vitest';
2+
import type { PrismaClient } from '@sourcebot/db';
3+
import { parseQuerySyntaxIntoIR } from './parser';
4+
import { ServiceErrorException } from '@/lib/serviceError';
5+
import { ErrorCode } from '@/lib/errorCodes';
6+
7+
describe('parseQuerySyntaxIntoIR', () => {
8+
it('throws a ServiceErrorException when a search context is not found', async () => {
9+
const prisma = {
10+
searchContext: {
11+
findUnique: async () => null,
12+
},
13+
} as unknown as PrismaClient;
14+
15+
const promise = parseQuerySyntaxIntoIR({
16+
query: 'Helpers context:0',
17+
options: {},
18+
prisma,
19+
});
20+
21+
await expect(promise).rejects.toBeInstanceOf(ServiceErrorException);
22+
await expect(promise).rejects.toMatchObject({
23+
serviceError: { errorCode: ErrorCode.SEARCH_CONTEXT_NOT_FOUND },
24+
});
25+
});
26+
27+
it('expands a search context into its repo set when found', async () => {
28+
const prisma = {
29+
searchContext: {
30+
findUnique: async () => ({
31+
repos: [{ name: 'org/repo-a' }, { name: 'org/repo-b' }],
32+
}),
33+
},
34+
} as unknown as PrismaClient;
35+
36+
const ir = await parseQuerySyntaxIntoIR({
37+
query: 'context:my-context',
38+
options: {},
39+
prisma,
40+
});
41+
42+
expect(JSON.stringify(ir)).toContain('org/repo-a');
43+
expect(JSON.stringify(ir)).toContain('org/repo-b');
44+
});
45+
});

packages/web/src/features/search/parser.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ export const parseQuerySyntaxIntoIR = async ({
114114
});
115115

116116
if (!context) {
117-
throw new Error(`Search context "${contextName}" not found`);
117+
throw new ServiceErrorException({
118+
statusCode: StatusCodes.NOT_FOUND,
119+
errorCode: ErrorCode.SEARCH_CONTEXT_NOT_FOUND,
120+
message: `Search context "${contextName}" not found`,
121+
});
118122
}
119123

120124
return context.repos.map((repo) => repo.name);

0 commit comments

Comments
 (0)