Skip to content

Commit

Permalink
Fix bug in bun when uploading files
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubno committed Nov 4, 2024
1 parent 6332979 commit 8c5c52a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/rare-planets-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'e2b': patch
---

Add explicit content header to fix bug in bun when uploading files
30 changes: 24 additions & 6 deletions packages/js-sdk/src/envd/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,29 @@ import createClient, { FetchResponse } from 'openapi-fetch'
import type { components, paths } from './schema.gen'
import { ConnectionConfig } from '../connectionConfig'
import { createApiLogger } from '../logs'
import { SandboxError, InvalidArgumentError, NotFoundError, NotEnoughSpaceError, formatSandboxTimeoutError, AuthenticationError } from '../errors'
import {
SandboxError,
InvalidArgumentError,
NotFoundError,
NotEnoughSpaceError,
formatSandboxTimeoutError,
AuthenticationError,
} from '../errors'
import { StartResponse } from './process/process_pb'
import { Code, ConnectError } from '@connectrpc/connect'
import { WatchDirResponse } from './filesystem/filesystem_pb'

export async function handleEnvdApiError<A, B, C extends `${string}/${string}`>(res: FetchResponse<A, B, C>) {
export async function handleEnvdApiError<A, B, C extends `${string}/${string}`>(
res: FetchResponse<A, B, C>
) {
if (!res.error) {
return
}

const message: string = typeof res.error == 'string' ? res.error : res.error?.message || await res.response.text()
const message: string =
typeof res.error == 'string'
? res.error
: res.error?.message || (await res.response.text())

switch (res.response.status) {
case 400:
Expand All @@ -23,7 +35,9 @@ export async function handleEnvdApiError<A, B, C extends `${string}/${string}`>(
case 404:
return new NotFoundError(message)
case 429:
return new SandboxError(`${res.response.status}: ${message}: The requests are being rate limited.`)
return new SandboxError(
`${res.response.status}: ${message}: The requests are being rate limited.`
)
case 502:
return formatSandboxTimeoutError(message)
case 507:
Expand All @@ -33,7 +47,9 @@ export async function handleEnvdApiError<A, B, C extends `${string}/${string}`>(
}
}

export async function handleProcessStartEvent(events: AsyncIterable<StartResponse>) {
export async function handleProcessStartEvent(
events: AsyncIterable<StartResponse>
) {
let startEvent: StartResponse

try {
Expand All @@ -54,7 +70,9 @@ export async function handleProcessStartEvent(events: AsyncIterable<StartRespons
return startEvent.event.event.value.pid
}

export async function handleWatchDirStartEvent(events: AsyncIterable<WatchDirResponse>) {
export async function handleWatchDirStartEvent(
events: AsyncIterable<WatchDirResponse>
) {
let startEvent: WatchDirResponse

try {
Expand Down
59 changes: 31 additions & 28 deletions packages/js-sdk/src/sandbox/filesystem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export interface WatchOpts extends FilesystemRequestOpts {
/**
* Timeout for the watch operation in **milliseconds**.
* You can pass `0` to disable the timeout.
*
*
* @default 60_000 // 60 seconds
*/
timeoutMs?: number
Expand Down Expand Up @@ -111,13 +111,13 @@ export class Filesystem {

/**
* Read file content as a `string`.
*
*
* You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.
*
*
* @param path path to the file.
* @param opts connection options.
* @param [opts.format] format of the file content—`text` by default.
*
*
* @returns file content as string
*/
async read(
Expand All @@ -126,13 +126,13 @@ export class Filesystem {
): Promise<string>
/**
* Read file content as a `Uint8Array`.
*
*
* You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.
*
*
* @param path path to the file.
* @param opts connection options.
* @param [opts.format] format of the file content—`bytes`.
*
*
* @returns file content as `Uint8Array`
*/
async read(
Expand All @@ -141,13 +141,13 @@ export class Filesystem {
): Promise<Uint8Array>
/**
* Read file content as a `Blob`.
*
*
* You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.
*
*
* @param path path to the file.
* @param opts connection options.
* @param [opts.format] format of the file content—`blob`.
*
*
* @returns file content as `Blob`
*/
async read(
Expand All @@ -156,13 +156,13 @@ export class Filesystem {
): Promise<Blob>
/**
* Read file content as a `ReadableStream`.
*
*
* You can pass `text`, `bytes`, `blob`, or `stream` to `opts.format` to change the return type.
*
*
* @param path path to the file.
* @param opts connection options.
* @param [opts.format] format of the file content—`stream`.
*
*
* @returns file content as `ReadableStream`
*/
async read(
Expand Down Expand Up @@ -207,18 +207,18 @@ export class Filesystem {

/**
* Write content to a file.
*
*
*
*
* Writing to a file that doesn't exist creates the file.
*
*
* Writing to a file that already exists overwrites the file.
*
*
* Writing to a file at path that doesn't exist creates the necessary directories.
*
* @param path path to file.
* @param data data to write to the file. Data can be a string, `ArrayBuffer`, `Blob`, or `ReadableStream`.
* @param opts connection options.
*
*
* @returns information about the written file
*/
async write(
Expand All @@ -243,7 +243,10 @@ export class Filesystem {
return fd
},
body: {},
signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),
headers: {
'Content-Type': 'multipart/form-data',
'Bun-Content-Type': 'temporary-fix', // https://github.com/oven-sh/bun/issues/14988
},
})

const err = await handleEnvdApiError(res)
Expand All @@ -264,7 +267,7 @@ export class Filesystem {
*
* @param path path to the directory.
* @param opts connection options.
*
*
* @returns list of entries in the sandbox filesystem directory.
*/
async list(path: string, opts?: FilesystemRequestOpts): Promise<EntryInfo[]> {
Expand Down Expand Up @@ -302,7 +305,7 @@ export class Filesystem {
*
* @param path path to a new directory. For example '/dirA/dirB' when creating 'dirB'.
* @param opts connection options.
*
*
* @returns `true` if the directory was created, `false` if it already exists.
*/
async makeDir(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {
Expand Down Expand Up @@ -333,7 +336,7 @@ export class Filesystem {
* @param oldPath path to the file or directory to rename.
* @param newPath new path for the file or directory.
* @param opts connection options.
*
*
* @returns information about renamed file or directory.
*/
async rename(
Expand Down Expand Up @@ -370,7 +373,7 @@ export class Filesystem {

/**
* Remove a file or directory.
*
*
* @param path path to a file or directory.
* @param opts connection options.
*/
Expand All @@ -393,7 +396,7 @@ export class Filesystem {
*
* @param path path to a file or a directory
* @param opts connection options.
*
*
* @returns `true` if the file or directory exists, `false` otherwise
*/
async exists(path: string, opts?: FilesystemRequestOpts): Promise<boolean> {
Expand Down Expand Up @@ -424,13 +427,13 @@ export class Filesystem {
* @param path path to directory to watch.
* @param onEvent callback to call when an event in the directory occurs.
* @param opts connection options.
*
*
* @returns `WatchHandle` object for stopping watching directory.
*/
async watchDir(
path: string,
onEvent: (event: FilesystemEvent) => void | Promise<void>,
opts?: WatchOpts,
opts?: WatchOpts
): Promise<WatchHandle> {
const requestTimeoutMs =
opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs
Expand All @@ -439,8 +442,8 @@ export class Filesystem {

const reqTimeout = requestTimeoutMs
? setTimeout(() => {
controller.abort()
}, requestTimeoutMs)
controller.abort()
}, requestTimeoutMs)
: undefined

const events = this.rpc.watchDir(
Expand Down

0 comments on commit 8c5c52a

Please sign in to comment.