Skip to content

Commit b52f497

Browse files
authored
Merge pull request #972 from finos/872-clarify-handling-of-malformed-context
872 Clarify malformed context handling
2 parents 88ee55a + 94f27cb commit b52f497

7 files changed

Lines changed: 42 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88

99
### Added
1010

11+
* Added a `MalformedContext` error to the `OpenError`, `ChannelError` and `ResolveError` enumerations, to be used when `broadcast`, `open`, `findIntents`, `raiseIntents` and other related functions are passed an invalid context Object. ([#972](https://github.com/finos/FDC3/pull/972))
1112
* Added error examples to the /v2 App Directory API routes ([#973](https://github.com/finos/FDC3/pull/973))
1213

1314
### Changed

docs/api/ref/Channel.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ Channel implementations should ensure that context messages broadcast by an appl
144144

145145
If you are working with complex context types composed of other simpler types (as recommended by the [FDC3 Context Data specification](../../context/spec#assumptions)) then you should broadcast each individual type (starting with the simpler types, followed by the complex type) that you want other apps to be able to respond to. Doing so allows applications to filter the context types they receive by adding listeners for specific context types.
146146

147+
If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the [`ChannelError.MalformedContext` error](Errors#channelerror).
148+
147149
#### Example
148150

149151
```javascript

docs/api/ref/DesktopAgent.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,12 @@ broadcast(context: Context): Promise<void>;
167167
168168
Publishes context to other apps on the desktop. Calling `broadcast` at the `DesktopAgent` scope will push the context to whatever _User Channel_ the app is joined to. If the app is not currently joined to a channel, calling `fdc3.broadcast` will have no effect. Apps can still directly broadcast and listen to context on any channel via the methods on the `Channel` class.
169169
170-
DesktopAgent implementations should ensure that context messages broadcast to a channel by an application joined to it are not delivered back to that same application.
170+
DesktopAgent implementations SHOULD ensure that context messages broadcast to a channel by an application joined to it are not delivered back to that same application.
171171
172172
If you are working with complex context types composed of other simpler types (as recommended by the [Context Data specification](../../context/spec#assumptions)) then you should broadcast each individual type (starting with the simpler types, followed by the complex type) that you want other apps to be able to respond to. Doing so allows applications to filter the context types they receive by adding listeners for specific context types.
173173
174+
If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the [`ChannelError.MalformedContext` error](Errors#channelerror).
175+
174176
#### Example
175177
176178
```js
@@ -274,7 +276,7 @@ Find out more information about a particular intent by passing its name, and opt
274276
`findIntent` is effectively granting programmatic access to the Desktop Agent's resolver.
275277
It returns a promise resolving to an `AppIntent` which provides details of the intent, its metadata and metadata about the apps and app instances that are registered to handle it. This can be used to raise the intent against a specific app or app instance.
276278
277-
If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. This includes the case where no apps are found that resolve the intent, when the `ResolveError.NoAppsFound` message should be used.
279+
If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. This includes the case where no apps are found that resolve the intent, when the [`ResolveError.NoAppsFound`](Errors#resolveerror) message should be used, and when an invalid context object is passed as an argument, when the [`ResolveError.MalformedContext`](Errors#resolveerror) message should be used.
278280
279281
Result types may be a type name, the string `"channel"` (which indicates that the app will return a channel) or a string indicating a channel that returns a specific type, e.g. `"channel<fdc3,instrument>"`. If intent resolution to an app returning a channel is requested, the desktop agent MUST include both apps that are registered as returning a channel and those registered as returning a channel with a specific type in the response.
280282
@@ -352,7 +354,7 @@ Find all the available intents for a particular context, and optionally a desire
352354
`findIntentsByContext` is effectively granting programmatic access to the Desktop Agent's resolver.
353355
A promise resolving to all the intents, their metadata and metadata about the apps and app instances that registered as handlers is returned, based on the context types the intents have registered.
354356
355-
If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. This includes the case where no intents with associated apps are found, when the `ResolveError.NoAppsFound` message should be used.
357+
If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. This includes the case where no intents with associated apps are found, when the `ResolveError.NoAppsFound` message should be used, and when an invalid context object is passed as an argument, when the [`ResolveError.MalformedContext`](Errors#resolveerror) message should be used.
356358
357359
The optional `resultType` argument may be a type name, the string `"channel"` (which indicates that the app will return a channel) or a string indicating a channel that returns a specific type, e.g. `"channel<fdc3,instrument>"`. If intent resolution to an app returning a channel is requested without a specified context type, the desktop agent MUST include both apps that are registered as returning a channel and those registered as returning a channel with a specific type in the response.
358360
@@ -634,7 +636,7 @@ Raises a specific intent for resolution against apps registered with the desktop
634636
The desktop agent MUST resolve the correct app to target based on the provided intent name and context data. If multiple matching apps are found, a method for resolving the intent to a target app, such as presenting the user with a resolver UI allowing them to pick an app, SHOULD be provided.
635637
Alternatively, the specific app or app instance to target can also be provided. A list of valid target applications and instances can be retrieved via [`findIntent`](DesktopAgent#findintent).
636638
637-
If a target app for the intent cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`.
639+
If a target app for the intent cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the [`ResolveError.MalformedContext`](Errors#resolveerror) string as its `message`.
638640
639641
If you wish to raise an intent without a context, use the `fdc3.nothing` context type. This type exists so that apps can explicitly declare support for raising an intent without context.
640642
@@ -700,7 +702,7 @@ Using `raiseIntentForContext` is similar to calling `findIntentsByContext`, and
700702
701703
Returns an `IntentResolution` object, see [`raiseIntent()`](#raiseintent) for details.
702704
703-
If a target intent and app cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`.
705+
If a target intent and app cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the [`ResolveError.MalformedContext`](Errors#resolveerror) string as its `message`.
704706
705707
#### Example
706708

docs/api/ref/Errors.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ enum ChannelError {
2323
* `getOrCreateChannel` method of the DesktopAgent (`fdc3`).
2424
*/
2525
CreationFailed = 'CreationFailed',
26+
27+
/** Returned if a call to the `broadcast` functions is made with an invalid
28+
* context argument. Contexts should be Objects with at least a `type` field
29+
* that has a `string` value.
30+
*/
31+
MalformedContext = 'MalformedContext',
2632
}
2733
```
2834

@@ -56,6 +62,12 @@ enum OpenError {
5662
* to handle the request.
5763
*/
5864
ResolverUnavailable = 'ResolverUnavailable',
65+
66+
/** Returned if a call to the `open` function is made with an invalid
67+
* context argument. Contexts should be Objects with at least a `type` field
68+
* that has a `string` value.
69+
*/
70+
MalformedContext = 'MalformedContext',
5971
}
6072
```
6173

@@ -105,6 +117,12 @@ export enum ResolveError {
105117
* handler within a timeout.
106118
*/
107119
IntentDeliveryFailed = 'IntentDeliveryFailed',
120+
121+
/** Returned if a call to one of the `raiseIntent` functions is made with an
122+
* invalid context argument. Contexts should be Objects with at least a `type`
123+
* field that has a `string` value.
124+
*/
125+
MalformedContext = 'MalformedContext',
108126
}
109127
```
110128

src/api/Channel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export interface Channel {
4848
* Channel implementations should ensure that context messages broadcast by an application on a channel should not be delivered back to that same application if they are joined to the channel.
4949
*
5050
* If you are working with complex context types composed of other simpler types (as recommended by the FDC3 Context Data specification) then you should broadcast each individual type (starting with the simpler types, followed by the complex type) that you want other apps to be able to respond to. Doing so allows applications to filter the context types they receive by adding listeners for specific context types.
51+
*
52+
* If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the `ChannelError.MalformedContext` error.
5153
*/
5254
broadcast(context: Context): Promise<void>;
5355

src/api/DesktopAgent.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export interface DesktopAgent {
5656
* It returns a promise resolving to the intent, its metadata and metadata about the apps and app instances that registered that intent.
5757
* This can be used to raise the intent against a specific app or app instance.
5858
*
59-
* If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the `ResolveError` enumeration. This includes the case where no apps are found that resolve the intent, when the `ResolveError.NoAppsFound` message should be used.
59+
* If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the `ResolveError` enumeration. This includes the case where no apps are found that resolve the intent, when the `ResolveError.NoAppsFound` message should be used, and when an invalid context object is passed as an argument, when the `ResolveError.MalformedContext` message should be used.
6060
*
6161
* Result types may be a type name, the string "channel" (which indicates that the app
6262
* will return a channel) or a string indicating a channel that returns a specific type,
@@ -133,7 +133,7 @@ export interface DesktopAgent {
133133
* `findIntentsByContext` is effectively granting programmatic access to the Desktop Agent's resolver.
134134
* It returns a promise resolving to an `AppIntent` which provides details of the intent, its metadata and metadata about the apps and app instances that are registered to handle it. This can be used to raise the intent against a specific app or app instance.
135135
*
136-
* If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the `ResolveError` enumeration. This includes the case where no intents with associated apps are found, when the `ResolveError.NoAppsFound` message should be used.
136+
* If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the `ResolveError` enumeration. This includes the case where no intents with associated apps are found, when the `ResolveError.NoAppsFound` message should be used, and when an invalid context object is passed as an argument, when the `ResolveError.MalformedContext` message should be used.
137137
*
138138
* The optional `resultType` argument may be a type name, the string "channel" (which indicates that the app
139139
* should return a channel) or a string indicating a channel that returns a specific type,
@@ -210,6 +210,8 @@ export interface DesktopAgent {
210210
* apps to be able to respond to. Doing so allows applications to filter the context types they receive by
211211
* adding listeners for specific context types.
212212
*
213+
* If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the `ChannelError.MalformedContext` error.
214+
*
213215
* ```javascript
214216
* const instrument = {
215217
* type: 'fdc3.instrument',
@@ -228,7 +230,7 @@ export interface DesktopAgent {
228230
* The desktop agent MUST resolve the correct app to target based on the provided intent name and context data. If multiple matching apps are found, the user MAY be presented with a Resolver UI allowing them to pick one, or another method of Resolution applied to select an app.
229231
* Alternatively, the specific app or app instance to target can also be provided. A list of valid target applications and instances can be retrieved via `findIntent`.
230232
*
231-
* If a target app for the intent cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the `ResolveError` enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`.
233+
* If a target app for the intent cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the `ResolveError` enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the `ResolveError.MalformedContext` string as its `message`.
232234
*
233235
* If you wish to raise an Intent without a context, use the `fdc3.nothing` context type. This type exists so that apps can explicitly declare support for raising an intent without context.
234236
*
@@ -278,7 +280,7 @@ export interface DesktopAgent {
278280
*
279281
* Returns an `IntentResolution` object, see `raiseIntent()` for details.
280282
*
281-
* If a target intent and app cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the `ResolveError` enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`.
283+
* If a target intent and app cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the `ResolveError` enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the `ResolveError.MalformedContext` string as its `message`.
282284
*
283285
* ```javascript
284286
* // Resolve against all intents registered for the type of the specified context

src/api/Errors.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export enum OpenError {
1313
AppTimeout = 'AppTimeout',
1414
/** Returned if the FDC3 desktop agent implementation is not currently able to handle the request.*/
1515
ResolverUnavailable = 'ResolverUnavailable',
16+
/** Returned if a call to the `open` function is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/
17+
MalformedContext = 'MalformedContext',
1618
}
1719

1820
/** Constants representing the errors that can be encountered when calling the `findIntent`, `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the DesktopAgent (`fdc3`). */
@@ -31,6 +33,8 @@ export enum ResolveError {
3133
TargetInstanceUnavailable = 'TargetInstanceUnavailable',
3234
/** Returned if the intent and context could not be delivered to the selected application or instance, for example because it has not added an intent handler within a timeout.*/
3335
IntentDeliveryFailed = 'IntentDeliveryFailed',
36+
/** Returned if a call to one of the `raiseIntent` functions is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/
37+
MalformedContext = 'MalformedContext',
3438
}
3539

3640
export enum ResultError {
@@ -47,4 +51,6 @@ export enum ChannelError {
4751
AccessDenied = 'AccessDenied',
4852
/** SHOULD be returned when a channel cannot be created or retrieved via the `getOrCreateChannel` method of the DesktopAgent (`fdc3`).*/
4953
CreationFailed = 'CreationFailed',
54+
/** Returned if a call to the `broadcast` functions is made with an invalid context argument. Contexts should be Objects with at least a `type` field that has a `string` value.*/
55+
MalformedContext = 'MalformedContext',
5056
}

0 commit comments

Comments
 (0)