Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/internal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ import {
uploadPartParser,
} from './xml-parser.ts'
import * as xmlParsers from './xml-parser.ts'
import { Logger } from './logger.ts'

const xml = new xml2js.Builder({ renderOpts: { pretty: false }, headless: true })

Expand Down Expand Up @@ -163,6 +164,7 @@ export interface ClientOptions {
port?: number
region?: Region
transport?: Transport
logger?: Logger
sessionToken?: string
partSize?: number
pathStyle?: boolean
Expand Down Expand Up @@ -198,6 +200,7 @@ type Part = {

export class TypedClient {
protected transport: Transport
protected logger: Logger
protected host: string
protected port: number
protected protocol: string
Expand Down Expand Up @@ -295,6 +298,12 @@ export class TypedClient {
transportAgent = params.transportAgent
}

if (params.logger) {
this.logger = params.logger;
} else {
this.logger = console;
}

// User Agent should always following the below style.
// Please open an issue to discuss any new changes here.
//
Expand Down Expand Up @@ -724,7 +733,7 @@ export class TypedClient {
reqOptions.headers.authorization = signV4(reqOptions, this.accessKey, this.secretKey, region, date, sha256sum)
}

const response = await requestWithRetry(this.transport, reqOptions, body)
const response = await requestWithRetry(this.transport, reqOptions, body, undefined, this.logger)
if (!response.statusCode) {
throw new Error("BUG: response doesn't have a statusCode")
}
Expand Down Expand Up @@ -2357,7 +2366,7 @@ export class TypedClient {

const res = await this.makeRequestAsync({ method, bucketName, objectName, query }, payload)
const body = await readAsBuffer(res)
return parseSelectObjectContentResponse(body)
return parseSelectObjectContentResponse(body, this.logger)
}

private async applyBucketLifecycle(bucketName: string, policyConfig: LifeCycleConfigParam): Promise<void> {
Expand Down
8 changes: 8 additions & 0 deletions src/internal/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Logger provides a common interface for logging.
* This interface is compatible with the default `console` logger.
*/
export interface Logger {
warn(message: string, ...optionalParams: never[]): void;
log(message: string, ...optionalParams: never[]): void;
}
5 changes: 3 additions & 2 deletions src/internal/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { pipeline } from 'node:stream'
import { promisify } from 'node:util'

import type { Transport } from './type.ts'
import { Logger } from './logger.ts'

const pipelineAsync = promisify(pipeline)

Expand Down Expand Up @@ -63,6 +64,7 @@ export async function requestWithRetry(
opt: https.RequestOptions,
body: Buffer | string | stream.Readable | null = null,
maxRetries: number = MAX_RETRIES,
logger: Logger,
): Promise<http.IncomingMessage> {
let attempt = 0
let isRetryable = false
Expand All @@ -85,8 +87,7 @@ export async function requestWithRetry(
throw new Error(`Request failed after ${maxRetries} retries: ${err}`)
}
const delay = getExpBackOffDelay(attempt)
// eslint-disable-next-line no-console
console.warn(
logger.warn(
`${new Date().toLocaleString()} Retrying request (attempt ${attempt}/${maxRetries}) after ${delay}ms due to: ${err}`,
)
await sleep(delay)
Expand Down
7 changes: 4 additions & 3 deletions src/internal/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
Tags,
} from './type.ts'
import { RETENTION_VALIDITY_UNITS } from './type.ts'
import { Logger } from './logger.ts'

// parse XML response for bucket region
export function parseBucketRegion(xml: string): string {
Expand Down Expand Up @@ -459,7 +460,7 @@ function extractHeaderValue(stream: stream.Readable) {
return Buffer.from(stream.read(bodyLen)).toString()
}

export function parseSelectObjectContentResponse(res: Buffer) {
export function parseSelectObjectContentResponse(res: Buffer, logger: Logger) {
const selectResults = new SelectResults({}) // will be returned

const responseStream = readableStream(res) // convert byte array to a readable responseStream
Expand Down Expand Up @@ -577,9 +578,9 @@ export function parseSelectObjectContentResponse(res: Buffer) {
default: {
// Continuation message: Not sure if it is supported. did not find a reference or any message in response.
// It does not have a payload.
const warningMessage = `Un implemented event detected ${messageType}.`
const warningMessage = `Unimplemented event detected ${messageType}.`
// eslint-disable-next-line no-console
console.warn(warningMessage)
logger.warn(warningMessage)
}
}
}
Expand Down