Skip to content

Commit 29fab0b

Browse files
hittytclaude
andcommitted
fix(sdk): classify not-found only by explicit FILE_NOT_FOUND code
Address review feedback: isFileNotFound() previously treated any HTTP 404 as not-found. A 404 whose body cannot be parsed is mapped to UNEXPECTED_RESPONSE and may signal a real endpoint/routing regression; downgrading those to DEBUG would hide genuine failures. Restrict detection to the explicit SandboxError.FILE_NOT_FOUND code (which the execd server returns for missing files) and add a regression test covering a bare 404 + UNEXPECTED_RESPONSE. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7d88455 commit 29fab0b

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

  • sdks/sandbox/kotlin/sandbox/src

sdks/sandbox/kotlin/sandbox/src/main/kotlin/com/alibaba/opensandbox/sandbox/infrastructure/adapters/converter/ExceptionConverter.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,16 @@ import com.alibaba.opensandbox.sandbox.api.execd.infrastructure.ServerException
4343
* Returns `true` when this throwable represents an expected "file or directory does not exist"
4444
* outcome rather than a genuine failure.
4545
*
46+
* Detection is intentionally restricted to the explicit [SandboxError.FILE_NOT_FOUND] server
47+
* error code rather than a bare HTTP 404. A 404 whose body cannot be parsed is mapped to
48+
* [SandboxError.UNEXPECTED_RESPONSE] and may indicate a real endpoint/routing/configuration
49+
* regression, which must stay loud (ERROR) instead of being silently downgraded.
50+
*
4651
* Callers (and the adapters themselves) use this to avoid treating a missing file as an error,
4752
* e.g. logging it at ERROR level with a full stack trace, which is just noise for a perfectly
4853
* normal control-flow case such as polling for a not-yet-created file.
4954
*/
50-
fun Throwable.isFileNotFound(): Boolean = this is SandboxApiException && (error.code == SandboxError.FILE_NOT_FOUND || statusCode == 404)
55+
fun Throwable.isFileNotFound(): Boolean = this is SandboxApiException && error.code == SandboxError.FILE_NOT_FOUND
5156

5257
fun Exception.toSandboxException(): SandboxException {
5358
return when (this) {

sdks/sandbox/kotlin/sandbox/src/test/kotlin/com/alibaba/opensandbox/sandbox/infrastructure/adapters/service/FilesystemAdapterTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,20 @@ class FilesystemAdapterTest {
121121
assertFalse(exception.isFileNotFound())
122122
}
123123

124+
@Test
125+
fun `isFileNotFound is false for a 404 without an explicit FILE_NOT_FOUND code`() {
126+
// A 404 whose body could not be parsed is mapped to UNEXPECTED_RESPONSE. It may indicate a
127+
// real endpoint/routing regression, so it must NOT be downgraded to a not-found condition.
128+
val exception =
129+
SandboxApiException(
130+
message = "Failed to read file. Status code: 404",
131+
statusCode = 404,
132+
error = SandboxError(SandboxError.UNEXPECTED_RESPONSE),
133+
)
134+
135+
assertFalse(exception.isFileNotFound())
136+
}
137+
124138
@Test
125139
fun `isFileNotFound is false for non-sandbox exceptions`() {
126140
assertFalse(RuntimeException("boom").isFileNotFound())

0 commit comments

Comments
 (0)