diff --git a/lib/src/core/consumed_thing.dart b/lib/src/core/consumed_thing.dart index 7efa6beb..fb5fd45e 100644 --- a/lib/src/core/consumed_thing.dart +++ b/lib/src/core/consumed_thing.dart @@ -36,6 +36,20 @@ class UnexpectedReponseException implements Exception { } } +/// This Exception is thrown when +class SubscriptionException implements Exception { + /// The error [message]. + final String message; + + /// Creates a new [SubscriptionException] from an error [message]. + SubscriptionException(this.message); + + @override + String toString() { + return message; + } +} + /// Implementation of the [scripting_api.ConsumedThing] interface. class ConsumedThing implements scripting_api.ConsumedThing { /// The [Servient] corresponding with this [ConsumedThing]. @@ -294,7 +308,8 @@ class ConsumedThing implements scripting_api.ConsumedThing { } if (_subscribedEvents.containsKey(eventName)) { - throw ArgumentError("ConsumedThing '$title' already has a function " + throw SubscriptionException( + "ConsumedThing '$title' already has a function " "subscribed to $eventName. You can only subscribe once."); } diff --git a/lib/src/core/servient.dart b/lib/src/core/servient.dart index dd382086..66a8c3ff 100644 --- a/lib/src/core/servient.dart +++ b/lib/src/core/servient.dart @@ -17,6 +17,17 @@ import 'protocol_interfaces/protocol_server.dart'; import 'security_provider.dart'; import 'wot.dart'; +/// Exception that is thrown by a [Servient]. +class ServientException implements Exception { + final String _message; + + /// Constructor + ServientException(this._message); + + @override + String toString() => "$runtimeType: $_message"; +} + // TODO(JKRhb): Documentation should be improved. /// A software stack that implements the WoT building blocks. /// @@ -194,7 +205,8 @@ class Servient { if (hasClientFor(scheme)) { return _clientFactories[scheme]!.createClient(_clientSecurityProvider); } else { - throw StateError('Servient has no ClientFactory for scheme $scheme'); + throw ServientException( + 'Servient has no ClientFactory for scheme $scheme'); } } } diff --git a/lib/src/core/wot.dart b/lib/src/core/wot.dart index df32f0e3..dc4b6d20 100644 --- a/lib/src/core/wot.dart +++ b/lib/src/core/wot.dart @@ -27,6 +27,22 @@ class ThingConsumptionException implements Exception { } } +/// This [Exception] is thrown if an error during the production of a +/// [ThingDescription] occurs. +class ThingProductionException implements Exception { + /// The identifier of the [ThingDescription] that triggered this [Exception]. + final String identifier; + + /// Constructor + ThingProductionException(this.identifier); + + @override + String toString() { + return "$runtimeType: An ExposedThing with identifier $identifier already " + "exists."; + } +} + /// Implementation of the [scripting_api.WoT] runtime interface. class WoT implements scripting_api.WoT { final Servient _servient; @@ -59,7 +75,8 @@ class WoT implements scripting_api.WoT { if (_servient.addThing(newThing)) { return newThing; } else { - throw StateError('Thing already exists: ${newThing.title}'); + final id = newThing.thingDescription.identifier; + throw ThingProductionException(id); } } diff --git a/lib/src/definitions/expected_response.dart b/lib/src/definitions/expected_response.dart index 287a4f72..8dbaa5ef 100644 --- a/lib/src/definitions/expected_response.dart +++ b/lib/src/definitions/expected_response.dart @@ -4,6 +4,8 @@ // // SPDX-License-Identifier: BSD-3-Clause +import 'validation/validation_exception.dart'; + /// Communication metadata describing the expected response message for the /// primary response. class ExpectedResponse { @@ -18,7 +20,7 @@ class ExpectedResponse { static String _parseContentType(dynamic contentType) { if (contentType is! String) { - throw ArgumentError("contentType of response map is not a String!"); + throw ValidationException("contentType of response map is not a String!"); } return contentType; } diff --git a/lib/src/definitions/form.dart b/lib/src/definitions/form.dart index 442ac989..eaaa26cc 100644 --- a/lib/src/definitions/form.dart +++ b/lib/src/definitions/form.dart @@ -385,7 +385,7 @@ class Form { } if (uriVariables == null) { - throw ArgumentError("The Form href $href contains URI variables " + throw ValidationException("The Form href $href contains URI variables " "but no values were provided as InteractionOptions."); } diff --git a/lib/src/definitions/link.dart b/lib/src/definitions/link.dart index 7e60f7bc..8824b7d0 100644 --- a/lib/src/definitions/link.dart +++ b/lib/src/definitions/link.dart @@ -4,6 +4,8 @@ // // SPDX-License-Identifier: BSD-3-Clause +import 'validation/validation_exception.dart'; + /// Represents an element of the `links` array in a Thing Description. /// /// A link can be viewed as a statement of the form "link context has a relation @@ -67,7 +69,7 @@ class Link { href = Uri.parse(hrefString); } else { // [href] *must* be initialized. - throw ArgumentError("'href' field must exist as a string.", "formJson"); + throw ValidationException("'href' field must exist as a string."); } if (json["type"] is String) { diff --git a/lib/src/definitions/security/oauth2_security_scheme.dart b/lib/src/definitions/security/oauth2_security_scheme.dart index d38d96db..21dc3072 100644 --- a/lib/src/definitions/security/oauth2_security_scheme.dart +++ b/lib/src/definitions/security/oauth2_security_scheme.dart @@ -4,6 +4,7 @@ // // SPDX-License-Identifier: BSD-3-Clause +import '../validation/validation_exception.dart'; import 'helper_functions.dart'; import 'security_scheme.dart'; @@ -92,7 +93,7 @@ class OAuth2SecurityScheme extends SecurityScheme { flow = jsonFlow; _parsedJsonFields.add("flow"); } else { - throw ArgumentError("flow must be of type 'string'!"); + throw ValidationException("flow must be of type 'string'!"); } parseAdditionalFields(additionalFields, json, _parsedJsonFields); diff --git a/lib/src/definitions/thing_description.dart b/lib/src/definitions/thing_description.dart index fd5fc619..c091d9d7 100644 --- a/lib/src/definitions/thing_description.dart +++ b/lib/src/definitions/thing_description.dart @@ -23,6 +23,7 @@ import 'security/psk_security_scheme.dart'; import 'security/security_scheme.dart'; import 'thing_model.dart'; import 'validation/thing_description_schema.dart'; +import 'validation/validation_exception.dart'; const _validContextValues = [ "https://www.w3.org/2019/wot/td/v1", @@ -196,7 +197,7 @@ class ThingDescription { if (titleJson is String) { title = titleJson; } else { - throw ArgumentError("Thing Description type is not a " + throw ValidationException("Thing Description type is not a " "String but ${title.runtimeType}"); } } diff --git a/lib/src/scripting_api/subscription.dart b/lib/src/scripting_api/subscription.dart index 773b9215..b189d7b2 100644 --- a/lib/src/scripting_api/subscription.dart +++ b/lib/src/scripting_api/subscription.dart @@ -9,6 +9,17 @@ import '../definitions/interaction_affordances/interaction_affordance.dart'; import '../definitions/operation_type.dart'; import 'interaction_options.dart'; +/// [Exception] that is thrown when error during the unsubscribe process occurs. +class UnsubscribeException implements Exception { + final String _message; + + /// Constructor. + UnsubscribeException(this._message); + + @override + String toString() => "$runtimeType: $_message"; +} + /// Indicates the type of the subscription. enum SubscriptionType { /// The subscription is the observation of a property. @@ -61,7 +72,7 @@ Form findUnsubscribeForm(InteractionAffordance interaction, final unsubscribeForm = _findFormByScoring(interaction, form, operationType); if (unsubscribeForm == null) { - throw StateError("Could not find matching form for unsubscribe"); + throw UnsubscribeException("Could not find matching form for unsubscribe"); } return unsubscribeForm;