Skip to content

Fix/@typescript eslint/no unnecessary condition#1483

Open
Pranav-0440 wants to merge 3 commits intoeclipse-thingweb:masterfrom
Pranav-0440:fix/@typescript-eslint/no-unnecessary-condition
Open

Fix/@typescript eslint/no unnecessary condition#1483
Pranav-0440 wants to merge 3 commits intoeclipse-thingweb:masterfrom
Pranav-0440:fix/@typescript-eslint/no-unnecessary-condition

Conversation

@Pranav-0440
Copy link

fixes - #1177

Add example and explanation for configuring PSK security scheme in CoapsClient.

Closes eclipse-thingweb#954

Signed-off-by: Pranav Ghorpade <pranavghorpade61@gmail.com>
Add example and explanation for configuring PSK security scheme in CoapsClient.

Closes eclipse-thingweb#954

Signed-off-by: Pranav Ghorpade <pranavghorpade61@gmail.com>
…ssary-condition rule

Signed-off-by: Pranav Ghorpade <pranavghorpade61@gmail.com>
Copilot AI review requested due to automatic review settings February 15, 2026 17:30
@Pranav-0440 Pranav-0440 requested a review from JKRhb as a code owner February 15, 2026 17:30
Copy link

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 enables the @typescript-eslint/no-unnecessary-condition rule for packages/binding-coap and adjusts the CoAP/CoAPs binding code to remove redundant nullish checks and tighten conditionals, alongside adding documentation for PSK-based DTLS (coaps://) usage.

Changes:

  • Add a package-level ESLint config enabling @typescript-eslint/no-unnecessary-condition (as a warning).
  • Refactor CoAP/CoAPs client/server code to remove unnecessary nullish coalescing/guards and refine request handling.
  • Extend binding-coap README with a PSK/DTLS (coaps://) usage example.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/binding-coap/src/mdns-introducer.ts Removes unnecessary fallback when iterating OS network interfaces.
packages/binding-coap/src/coaps-client.ts Tightens undefined checks and removes optional chaining on typed values.
packages/binding-coap/src/coap-server.ts Refactors request routing and multi-property read handling; adjusts affordance typing.
packages/binding-coap/src/coap-client.ts Makes Content-Format handling more type-safe when reading headers.
packages/binding-coap/eslint.config.mjs Adds per-package rule enablement for no-unnecessary-condition.
packages/binding-coap/README.md Documents how to use PSK with CoAPs (DTLS).
Comments suppressed due to low confidence (1)

packages/binding-coap/src/coap-server.ts:518

  • affordanceKey can be missing for requests like /thing/actions or /thing/events (e.g., trailing slash / short path). In those cases handleActionRequest/handleEventRequest will index into thing.actions[affordanceKey]/thing.events[affordanceKey] with undefined and then dereference .forms, causing a runtime error. Please add an explicit !affordanceKey check here (send 4.04 or 4.00) before dispatching.
            case this.ACTION_DIR:
                this.handleActionRequest(thing, affordanceKey, req, res, contentType);
                break;
            case this.EVENT_DIR:
                this.handleEventRequest(thing, affordanceKey, req, res, contentType);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +621 to +632
if (
content.type !== ContentSerdes.DEFAULT &&
content.type !== "application/json"
) {
continue;
}
const buffer = await content.toBuffer();
const parsed = JSON.parse(buffer.toString());

recordResponse[key] = parsed;
} catch {
// Ignore non-JSON properties
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The content.type filter is overly strict and also redundant (ContentSerdes.DEFAULT is already application/json). As written it will skip valid JSON-based media types like application/ld+json or JSON with parameters (e.g. application/json; charset=utf-8). Prefer using ContentSerdes.getMediaType(content.type) for comparison, or better: let ContentSerdes.contentToValue handle decoding based on the actual content type.

Suggested change
if (
content.type !== ContentSerdes.DEFAULT &&
content.type !== "application/json"
) {
continue;
}
const buffer = await content.toBuffer();
const parsed = JSON.parse(buffer.toString());
recordResponse[key] = parsed;
} catch {
// Ignore non-JSON properties
const parsed = await ContentSerdes.get().contentToValue(content);
recordResponse[key] = parsed as DataSchemaValue;
} catch {
// Ignore non-JSON or unsupported properties

Copilot uses AI. Check for mistakes.
Comment on lines +628 to +632
const parsed = JSON.parse(buffer.toString());

recordResponse[key] = parsed;
} catch {
// Ignore non-JSON properties
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

Using JSON.parse here changes behavior compared to ContentSerdes.contentToValue/JsonCodec: it will throw on non-JSON payloads (e.g. plain strings without quotes) and the catch block then drops that property entirely. This breaks the prior relaxed decoding behavior (and will omit string-valued properties encoded as non-JSON). Consider switching back to ContentSerdes.get().contentToValue({ type: content.type, body: buffer }, /* schema */ ...) so decoding is consistent with the rest of the stack.

Suggested change
const parsed = JSON.parse(buffer.toString());
recordResponse[key] = parsed;
} catch {
// Ignore non-JSON properties
const parsed = ContentSerdes.get().contentToValue(
{ type: content.type, body: buffer },
undefined
);
recordResponse[key] = parsed;
} catch {
// Ignore non-JSON properties or decoding errors

Copilot uses AI. Check for mistakes.
Comment on lines +173 to 176
if (security.scheme === "psk" && credentials !== undefined) {
this.authorization = { psk: {} };
this.authorization.psk[credentials.identity] = credentials.psk;
} else if (security.scheme === "apikey") {
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

credentials is typed as pskSecurityParameters (currently an index-signature map), but it is used as if it had { identity: string; psk: string } properties (credentials.identity / credentials.psk). This is inconsistent with the typing and can lead to incorrect usage by callers; consider updating the pskSecurityParameters type (or adjusting the code) so the type matches the actual expected shape.

Copilot uses AI. Check for mistakes.
@@ -145,11 +148,6 @@ export default class CoapServer implements ProtocolServer {
const port = this.getPort();
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

expose() now proceeds even when getPort() returns -1 (server not listening). That will generate invalid coap://...:-1/... URLs and register mDNS with an invalid port. Consider restoring the guard (warn + return) or throwing a clear error when port === -1 to prevent exposing before start() completes.

Suggested change
const port = this.getPort();
const port = this.getPort();
if (port === -1) {
warn(
`CoapServer expose() called for '${thing.title}' but server is not listening (port -1). ` +
"Did you forget to call start()?"
);
return;
}

Copilot uses AI. Check for mistakes.
@@ -554,11 +551,6 @@ export default class CoapServer implements ProtocolServer {
) {
const property = thing.properties[affordanceKey];

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

thing.properties[affordanceKey] can be undefined for unknown property names, but the method now passes it straight into handleReadProperty/handleWriteProperty and later reads property.readOnly, which will throw. Add a not-found handling branch when property is undefined (likely a 4.04), instead of continuing.

Suggested change
if (!property) {
this.sendResponse(res, "4.04", "Property not found");
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines 775 to 779
const action = thing.actions[affordanceKey];

if (action == null) {
this.sendNotFoundResponse(res);
return;
}

if (req.method !== "POST") {
this.sendMethodNotAllowedResponse(res);
return;
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

action can be undefined when an unknown action name (or missing segment) is requested, but handleActionRequest later dereferences action.forms / action.uriVariables unconditionally. Please add/restore a not-found guard (e.g., 4.04) when action is undefined to avoid runtime exceptions.

Copilot uses AI. Check for mistakes.
@@ -837,19 +831,14 @@ export default class CoapServer implements ProtocolServer {
) {
const event = thing.events[affordanceKey];

Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

event can be undefined when an unknown event name (or missing segment) is requested, but the code later dereferences event.forms / event.uriVariables unconditionally. Please add/restore a not-found guard (4.04) when event is undefined to prevent runtime exceptions.

Suggested change
if (!event) {
debug(
`CoapServer on port ${this.getPort()} received request for unknown event '${affordanceKey}' from ${Helpers.toUriLiteral(
req.rsinfo.address
)}:${req.rsinfo.port}`
);
this.sendResponse(res, "4.04", "Not Found");
return;
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant