Fix/@typescript eslint/no unnecessary condition#1483
Fix/@typescript eslint/no unnecessary condition#1483Pranav-0440 wants to merge 3 commits intoeclipse-thingweb:masterfrom
Conversation
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>
There was a problem hiding this comment.
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-coapREADME 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
affordanceKeycan be missing for requests like/thing/actionsor/thing/events(e.g., trailing slash / short path). In those caseshandleActionRequest/handleEventRequestwill index intothing.actions[affordanceKey]/thing.events[affordanceKey]withundefinedand then dereference.forms, causing a runtime error. Please add an explicit!affordanceKeycheck 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.
| 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 |
There was a problem hiding this comment.
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.
| 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 |
| const parsed = JSON.parse(buffer.toString()); | ||
|
|
||
| recordResponse[key] = parsed; | ||
| } catch { | ||
| // Ignore non-JSON properties |
There was a problem hiding this comment.
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.
| 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 |
| if (security.scheme === "psk" && credentials !== undefined) { | ||
| this.authorization = { psk: {} }; | ||
| this.authorization.psk[credentials.identity] = credentials.psk; | ||
| } else if (security.scheme === "apikey") { |
There was a problem hiding this comment.
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.
| @@ -145,11 +148,6 @@ export default class CoapServer implements ProtocolServer { | |||
| const port = this.getPort(); | |||
There was a problem hiding this comment.
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.
| 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; | |
| } |
| @@ -554,11 +551,6 @@ export default class CoapServer implements ProtocolServer { | |||
| ) { | |||
| const property = thing.properties[affordanceKey]; | |||
|
|
|||
There was a problem hiding this comment.
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.
| if (!property) { | |
| this.sendResponse(res, "4.04", "Property not found"); | |
| return; | |
| } |
| const action = thing.actions[affordanceKey]; | ||
|
|
||
| if (action == null) { | ||
| this.sendNotFoundResponse(res); | ||
| return; | ||
| } | ||
|
|
||
| if (req.method !== "POST") { | ||
| this.sendMethodNotAllowedResponse(res); | ||
| return; |
There was a problem hiding this comment.
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.
| @@ -837,19 +831,14 @@ export default class CoapServer implements ProtocolServer { | |||
| ) { | |||
| const event = thing.events[affordanceKey]; | |||
|
|
|||
There was a problem hiding this comment.
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.
| 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; | |
| } |
fixes - #1177