diff --git a/index.html b/index.html index f527b7a..8ab9477 100644 --- a/index.html +++ b/index.html @@ -355,7 +355,7 @@ The generic WoT terminology is defined in [[!wot-architecture11]]: Thing, Thing Description (in short TD), Partial TD, Web of Things (in short WoT), WoT Interface, Protocol Bindings, WoT Runtime, Consuming a Thing Description, TD Directory, Property, Action, Event, DataSchema, Form, - SecurityScheme, NoSecurityScheme etc. + SecurityScheme, NoSecurityScheme, AdditionalExpectedResponse etc.

WoT Interaction is a synonym for Interaction Affordance. @@ -1434,15 +1434,95 @@

The ActionInteractionOutput interface

title="Error handling"/>
Error handling in WoT interactions
-

- This topic is still being discussed in - Issue #200. - A standardized error mapping would be needed in order to ensure consistency - in mapping script errors to protocol errors and vice versa. In particular, - when algorithms say "error received from the Protocol Bindings", - that will be factored out as an explicit error mapping algorithm. Currently, - that is encapsulated by implementations. -

+ +
+

The InteractionError interface

+

+ Currently, we are looking for wider implementation of the following section. + The algorithm presented here might be subject to changes in the future. +

+

+ Represents an error that occurred during a WoT Interaction with + additional diagnostic information from the Thing in the form of + response data associated with an AdditionalExpectedResponse defined in + the Thing Description. +

+
+        [SecureContext, Exposed=(Window,Worker)]
+        interface InteractionError : Error {
+          constructor(DOMString message, InteractionOutput data);
+          readonly attribute InteractionOutput data;
+        };
+      
+

+ The data attribute represents + the {{InteractionOutput}} object containing the response payload from the + failed WoT Interaction. +

+
+ +
+

The handle interaction error response algorithm

+

+ This algorithm is invoked by any {{ConsumedThing}} method that performs a WoT Interaction. + It processes error responses returned by the Protocol Bindings and determines whether to + throw an {{InteractionError}} or map the response to a {{DOMException}}. +

+

+ To handle interaction error response given |error|, |form:Form| and |response|, + run these steps: +

+
    +
  1. + if |response| is not defined or null, attempt to map |error| + to a suitable {{DOMException}} or, if none, to {{OperationError}}. + Return that error and stop. +
  2. +
  3. + Let |additionalResponses| be |form|.|additionalResponses|, if it exists. +
  4. +
  5. + Let |binding| be the binding that was used to make the request which resulted in |response|. +
  6. +
  7. + If |additionalResponses| is defined, for each |responseEntry:AdditionalExpectedResponse| in + |additionalResponses|: +
      +
    1. + Let |match| be a boolean expression that checks if |response| matches a |responseEntry| according to |binding| +
    2. +
    3. + If |responseEntry|.|success| is `false` or not defined and if |match| is `true` for |responseEntry|, + then run these sub-steps: +
        +
      1. + Let |responseSchema| be |responseEntry|.|schema|, if it exists. +
      2. +
      3. + Let |errorOutput:InteractionOutput| be the result of running + parse interaction response on |response|, |form|, and + |responseSchema|. +
      4. +
      5. + Return a newly constructed {{InteractionError}}, using a message + derived from the |binding| or |error| as first argument, and |errorOutput| + as second argument. +
      6. +
      +
    4. +
    +
  8. +
  9. + If no match was found in |additionalResponses| but |binding| indicates + a failure, attempt to map the error + to a suitable {{DOMException}} or other appropriate + error type. +
  10. +
  11. + Otherwise, return {{OperationError}}. +
  12. +
+
@@ -1635,7 +1715,18 @@

The readProperty() method

using |form| and the optional URI templates given in |options|.|uriVariables|.
  • - If the request fails, [=reject=] |promise| with the error received from the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the followingsub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Let |response| be the response received to the request. @@ -1678,11 +1769,26 @@

    The readMultipleProperties() method

  • Let |result:object| be an object and for each string |name:string| in |propertyNames| add a property with key |name| and the value `null`.
  • +
  • + If this cannot be done with a single request with the Protocol Bindings, [=reject=] |promise| with a + {{NotSupportedError}} and stop. +
  • Make a request to the underlying platform (via the Protocol Bindings) to retrieve the Property values given by |propertyNames| with |form| and optional URI templates given in |options|' |uriVariables|.
  • - If this cannot be done with a single request with the Protocol Bindings, [=reject=] |promise| with a {{NotSupportedError}} and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Process the response and for each |key| in |result|, run the following @@ -1750,7 +1856,18 @@

    The readAllProperties() method

    If this cannot be done with a single request with the Protocol Bindings of the Thing, then [=reject=] |promise| with a {{NotSupportedError}} and stop.
  • - If the request fails, [=reject=] |promise| with the error received from the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Process the reply and let |result:object| be an object with the keys and values obtained in the reply. @@ -1820,7 +1937,18 @@

    The writeProperty() method

    |options|' |uriVariables|.
  • - If the request fails, [=reject=] |promise| with the error received from the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Otherwise [=resolve=] |promise|. @@ -1904,8 +2032,18 @@

    The writeMultipleProperties() method

    with a {{NotSupportedError}} and stop.
  • - If the request fails, return the error received from the - Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Otherwise [=resolve=] |promise|. @@ -1993,8 +2131,18 @@

    The observeProperty() method

    optional URI templates given in |options|' |uriVariables|.
  • - If the request fails, [=reject=] |promise| with the error received from - the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • [=map/Set=] |thing|.{{ConsumedThing/[[activeObservations]]}}[|propertyName] to |subscription| and [=resolve=] |promise|. @@ -2083,7 +2231,18 @@

    The invokeAction() method

    Make a request to the underlying platform (via the Protocol Bindings) to invoke the Action identified by |actionName| given |args| and |options|.|uriVariables|.
  • - If the request fails locally or returns an error over the network, [=reject=] |promise| with the error received from the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |form| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • Let |value| be the reply returned in the reply. @@ -2172,8 +2331,18 @@

    The subscribeEvent() method

    and optional subscription data given in |options|.|data|.
  • - If the request fails, [=reject=] |promise| with the error received from - the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + {{Subscription/[[form]]}} and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
  • [=map/Set=] |eventName| to |thing|.{{ConsumedThing/[[activeSubscriptions]]}}[|eventName|] to |subscription|. @@ -2389,8 +2558,22 @@

    The stop() method

    unsubscribe data given in |options|.|data|.
  • - If the request fails, [=reject=] |promise| with the error received from - the Protocol Bindings and stop. + If the request fails with error |receivedError| and optionally |failedResponse|, + run the following sub-steps: +
      +
    1. + let |error| be the result of running + handle interaction error response given the |receivedError| + |unsubscribeForm| and |failedResponse|. +
    2. +
    3. + [=Reject=] |promise| with |error| and stop. +
    4. +
    5. + If the underlying platform receives further notifications for this + subscription, implementations SHOULD silently suppress them. +
    6. +
  • Otherwise: