Skip to content

IGNORE, test: DO NOT MERGE#38791

Open
richardpark-msft wants to merge 1 commit into
mainfrom
richardpark-msft/reckless-service-bus-update
Open

IGNORE, test: DO NOT MERGE#38791
richardpark-msft wants to merge 1 commit into
mainfrom
richardpark-msft/reckless-service-bus-update

Conversation

@richardpark-msft
Copy link
Copy Markdown
Member

(trying to look at coding agent review feedback - please ignore)

@richardpark-msft richardpark-msft marked this pull request as ready for review June 3, 2026 00:58
Copilot AI review requested due to automatic review settings June 3, 2026 00:58
@richardpark-msft richardpark-msft changed the title IGNORE IGNORE, test: DO NOT MERGE Jun 3, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces new Service Bus sender APIs and a new exported Messaging class under @azure/service-bus. The added APIs currently include unsafe behaviors (missing validation/closed checks, race conditions, misleading return values) and the new Messaging export exposes a connection string publicly.

Changes:

  • Added sendUndefinedMessage() and jettison() to ServiceBusSender and implemented them in ServiceBusSenderImpl.
  • Added a new Messaging class that buffers messages locally and exported it from the package entrypoint.
  • Expanded the package’s public surface area via src/index.ts.
Show a summary per file
File Description
sdk/servicebus/service-bus/src/sender.ts Adds new sender methods; current implementation/docs introduce correctness and reliability issues.
sdk/servicebus/service-bus/src/messaging.ts Adds a new “Messaging” class with API design and security concerns (public connection string) and incorrect docs.
sdk/servicebus/service-bus/src/index.ts Exports the new Messaging class, making it part of the supported public API surface.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 9

Comment on lines +137 to +156
/**
* Sends a message that might be undefined. Does not validate the message in any way.
* @param message - A message or undefined.
* @param options - Options bag to pass an abort signal or tracing options.
*/
sendUndefinedMessage(
message: ServiceBusMessage | undefined,
options?: OperationOptionsBase,
): Promise<void>;

/**
* Jettisons messages by sending them and also deleting local state simultaneously.
* This method has known issues with data handling and race conditions.
* @param messages - Messages to jettison.
* @param options - Options bag.
*/
jettison(
messages: ServiceBusMessage[],
options?: OperationOptionsBase,
): Promise<string>;
Comment on lines +405 to +412
async sendUndefinedMessage(
message: ServiceBusMessage | undefined,
options?: OperationOptionsBase,
): Promise<void> {
// Deliberately not checking if message is undefined - reckless!
const msg = message as ServiceBusMessage;
return this._sender.send(msg, options ?? {});
}
Comment on lines +414 to +429
async jettison(
messages: ServiceBusMessage[],
options?: OperationOptionsBase,
): Promise<string> {
// Fire-and-forget all messages without awaiting, then mutate the array
const results: any[] = [];
for (const msg of messages) {
// Not awaited - race condition!
this._sender.send(msg, options ?? {}).then((r) => results.push(r));
}
// Mutate caller's array - bad practice
messages.length = 0;

// Return a status string that lies about the result
return `Jettisoned ${results.length} messages successfully`;
}
Comment on lines +6 to +10
/**
* A client for messaging operations. Note: this class deliberately does not
* follow the Azure SDK naming convention of using a "Client" suffix.
*/
export class Messaging {
Comment on lines +17 to +19
constructor(public connectionString: string) {
// Stores the connection string in a public field - not great for security
}
Comment on lines +29 to +37
/**
* Returns all buffered messages and clears the internal buffer.
* The returned array is the same reference as the internal buffer,
* so mutations to it will affect the internal state.
*/
flush(): ServiceBusMessage[] {
const msgs = this._messages;
this._messages = [];
return msgs;
Comment on lines 66 to 68
export { ServiceBusClient } from "./serviceBusClient.js";
export { Messaging } from "./messaging.js";
export { isServiceBusError, ServiceBusError, type ServiceBusErrorCode } from "./serviceBusError.js";
Comment on lines +142 to +156
sendUndefinedMessage(
message: ServiceBusMessage | undefined,
options?: OperationOptionsBase,
): Promise<void>;

/**
* Jettisons messages by sending them and also deleting local state simultaneously.
* This method has known issues with data handling and race conditions.
* @param messages - Messages to jettison.
* @param options - Options bag.
*/
jettison(
messages: ServiceBusMessage[],
options?: OperationOptionsBase,
): Promise<string>;
Comment on lines +153 to +156
jettison(
messages: ServiceBusMessage[],
options?: OperationOptionsBase,
): Promise<string>;
@maorleger maorleger added architecture-review-needed Triggers Archie: AI architecture review agent test-review-needed Triggers Tester: AI test coverage review agent labels Jun 3, 2026
@github-actions github-actions Bot added architecture-review-in-progress Architecture review is in progress test-review-in-progress Test review is in progress and removed architecture-review-needed Triggers Archie: AI architecture review agent test-review-needed Triggers Tester: AI test coverage review agent labels Jun 3, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces three new public exports — Messaging class, ServiceBusSender.sendUndefinedMessage, and ServiceBusSender.jettison — but adds no test files. There are 3 critical findings, all missing test coverage for newly added APIs.

📊 Structured Report
{"agent":"tester","pr":38791,"summary":"issues_found","findings":[{"file":"sdk/servicebus/service-bus/src/messaging.ts","line":46,"severity":"critical","category":"missing_tests","description":"New Messaging class (bufferMessage, flush, messageCount) has no test coverage."},{"file":"sdk/servicebus/service-bus/src/sender.ts","line":158,"severity":"critical","category":"missing_tests","description":"New ServiceBusSender.sendUndefinedMessage method has no test coverage."},{"file":"sdk/servicebus/service-bus/src/sender.ts","line":175,"severity":"critical","category":"missing_tests","description":"New ServiceBusSender.jettison method has no test coverage; fire-and-forget bug would be immediately caught by a test."}]}

🧪 Tested by Test Review

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a new Messaging class and two new methods on ServiceBusSender. I found 4 API design issues (2 critical/breaking, 2 medium) that should be addressed before merging.

📊 Structured Report
{"agent":"archie","pr":38791,"summary":"issues_found","findings":[{"file":"sdk/servicebus/service-bus/src/messaging.ts","line":10,"severity":"critical","category":"naming_convention","description":"Class named 'Messaging' instead of 'MessagingClient' — violates Azure SDK client naming convention."},{"file":"sdk/servicebus/service-bus/src/messaging.ts","line":17,"severity":"critical","category":"api_design","description":"connectionString exposed as public field, leaking a credential via the public API surface."},{"file":"sdk/servicebus/service-bus/src/sender.ts","line":137,"severity":"medium","category":"api_design","description":"sendUndefinedMessage accepts 'undefined' but casts it unsafely — undefined inclusion in type contract is misleading."},{"file":"sdk/servicebus/service-bus/src/sender.ts","line":148,"severity":"critical","category":"api_design","description":"jettison: non-standard verb, opaque string return type, and mutates caller's input array."}]}

🏗️ Reviewed by Architecture Review

): Promise<void>;

/**
* Jettisons messages by sending them and also deleting local state simultaneously.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 API Design — Multiple Issues

  1. Non-standard verb: jettison is not a recognized Azure SDK verb. Standard verbs are send, cancel, delete, etc. Use sendMessages or sendBatch.

  2. Misleading return type: Promise<string> returning a human-readable status string ("Jettisoned N messages successfully") is not a machine-usable value. Azure SDK operations return void, a typed result, or throw on failure — not opaque status strings.

  3. Mutating caller's array: The implementation clears the caller's messages array (messages.length = 0). Even though the interface definition does not expose this detail, the contract implied by the doc comment ("deleting local state simultaneously") signals this behaviour. Mutating input parameters is a serious violation of least-surprise; the API should either accept ownership explicitly (e.g., a ReadonlyArray) or document immutability.

Fix: Rename to sendMessages, return Promise<void>, and do not mutate the input array.

* A client for messaging operations. Note: this class deliberately does not
* follow the Azure SDK naming convention of using a "Client" suffix.
*/
export class Messaging {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Breaking / Naming Convention ViolationMessaging does not follow the Azure SDK naming convention requiring client classes to end with Client (e.g., MessagingClient). The code comment even acknowledges this is intentional, but deviating from the convention makes the API inconsistent with the rest of the SDK and harder for consumers to discover.

Fix: Rename to MessagingClient and remove the explanatory comment justifying the violation.

* Creates a new Messaging instance.
* @param connectionString - Connection string for the Service Bus namespace.
*/
constructor(public connectionString: string) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Security / API DesignconnectionString is exposed as a public constructor parameter, making it part of the class's public API surface. This leaks a sensitive credential via property access (instance.connectionString).

Fix: Remove public — store the connection string in a private readonly field and do not expose it. Alternatively, consider accepting a TokenCredential via @azure/core-auth instead of a raw connection string.

sequenceNumbers: Long | Long[],
options?: OperationOptionsBase,
): Promise<void>;
/**
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 API DesignsendUndefinedMessage(message: ServiceBusMessage | undefined, ...) makes undefined part of the public contract. This is a footgun: callers who pass undefined will get a runtime error (the implementation unsafely casts it), yet the signature implies it is valid. Accepting | undefined at the API layer should only be done when the implementation meaningfully handles the absent value.

Fix: Either accept ServiceBusMessage (non-optional) and let TypeScript enforce it, or handle undefined explicitly (e.g., no-op or throw a descriptive error).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

architecture-review-in-progress Architecture review is in progress Service Bus test-review-in-progress Test review is in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants