Skip to content

Commit 39ccee8

Browse files
authored
Merge pull request #173 from eclipse-thingweb/validation-exception
feat!: use FormatException instead of custom ValidationException
2 parents 237a259 + f7ee480 commit 39ccee8

19 files changed

+39
-86
lines changed

lib/src/binding_coap/coap_extensions.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extension CoapFormExtension on AugmentedForm {
8383
return BlockSize.fromDecodedValue(value);
8484
// ignore: avoid_catching_errors
8585
} on ArgumentError {
86-
throw ValidationException(
86+
throw FormatException(
8787
"Encountered invalid blocksize $value in CoAP form",
8888
);
8989
}

lib/src/binding_mqtt/mqtt_extensions.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ extension MqttFormExtension on AugmentedForm {
138138

139139
// TODO: This validation should maybe already happen earlier.
140140
if (qosValue != null) {
141-
throw ValidationException(
141+
throw FormatException(
142142
"Encountered unknown QoS value $qosValue. "
143143
"in form with href $href of Thing Description with Identifier "
144144
"$tdIdentifier.",

lib/src/core/definitions/context.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import "package:collection/collection.dart";
88
import "package:curie/curie.dart";
99
import "package:meta/meta.dart";
1010

11-
import "../exceptions.dart";
12-
1311
const _tdVersion10ContextUrl = "https://www.w3.org/2019/wot/td/v1";
1412
const _tdVersion11ContextUrl = "https://www.w3.org/2022/wot/td/v1.1";
1513

@@ -30,14 +28,14 @@ final class Context {
3028
final firstContextEntry = contextEntries.firstOrNull;
3129

3230
if (firstContextEntry is! SingleContextEntry) {
33-
throw const ValidationException("Missing TD context URL.");
31+
throw const FormatException("Missing TD context URL.");
3432
}
3533

3634
final firstContextValue = firstContextEntry.value;
3735

3836
if (![_tdVersion10ContextUrl, _tdVersion11ContextUrl]
3937
.contains(firstContextValue)) {
40-
throw ValidationException(
38+
throw FormatException(
4139
"Encountered invalid TD context URL $firstContextEntry",
4240
);
4341
}
@@ -142,12 +140,12 @@ final class SingleContextEntry extends ContextEntry {
142140
/// Creates a new [SingleContextEntry] from a [string] that represents a URI.
143141
///
144142
/// If the [string] should not be a valid URI, this factory constructor will
145-
/// throw a [ValidationException].
143+
/// throw a [FormatException].
146144
factory SingleContextEntry.fromString(String string) {
147145
final parsedUri = Uri.tryParse(string);
148146

149147
if (parsedUri == null) {
150-
throw ValidationException("Encountered invalid URI $string");
148+
throw FormatException("Encountered invalid URI $string");
151149
}
152150

153151
return SingleContextEntry(parsedUri);

lib/src/core/definitions/extensions/json_parser.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import "package:curie/curie.dart";
88

9-
import "../../exceptions.dart";
109
import "../additional_expected_response.dart";
1110
import "../context.dart";
1211
import "../data_schema.dart";
@@ -96,7 +95,7 @@ extension ParseField on Map<String, dynamic> {
9695
}
9796

9897
/// Parses a single field with a given [name] and throws a
99-
/// [ValidationException] if the field is not present or does not have the
98+
/// [FormatException] if the field is not present or does not have the
10099
/// type [T].
101100
///
102101
/// Like [parseField], it adds the field [name] to the set of [parsedFields],
@@ -105,7 +104,7 @@ extension ParseField on Map<String, dynamic> {
105104
final fieldValue = parseField(name, parsedFields);
106105

107106
if (fieldValue is! T) {
108-
throw ValidationException(
107+
throw FormatException(
109108
"Value for field $name has wrong data type or is missing. "
110109
"Expected ${T.runtimeType}, got ${fieldValue.runtimeType}.",
111110
);
@@ -115,7 +114,7 @@ extension ParseField on Map<String, dynamic> {
115114
}
116115

117116
/// Parses a single field with a given [name] as a [Uri] and throws a
118-
/// [ValidationException] if the field is not present or cannot be parsed.
117+
/// [FormatException] if the field is not present or cannot be parsed.
119118
///
120119
/// If a [Set] of [parsedFields] is passed to this function, the field [name]
121120
/// will added. This can be used for filtering when parsing additional fields.
@@ -284,7 +283,7 @@ extension ParseField on Map<String, dynamic> {
284283
return forms;
285284
}
286285

287-
throw const ValidationException(
286+
throw const FormatException(
288287
'Missing "forms" member in InteractionAffordance',
289288
);
290289
}
@@ -610,7 +609,7 @@ Iterable<ContextEntry> _parseContextEntries(dynamic json) sync* {
610609
final value = entry.value;
611610

612611
if (value is! String) {
613-
throw ValidationException(
612+
throw FormatException(
614613
"Expected $value to be a String or a Map<String, String> "
615614
"as @context entry, got ${value.runtimeType} instead.");
616615
}
@@ -625,7 +624,7 @@ Iterable<ContextEntry> _parseContextEntries(dynamic json) sync* {
625624
});
626625
}
627626
default:
628-
throw ValidationException(
627+
throw FormatException(
629628
"Expected the @context entry $json to "
630629
"either be a String or a Map<String, String>, "
631630
"got ${json.runtimeType} instead.",

lib/src/core/definitions/operation_type.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
//
55
// SPDX-License-Identifier: BSD-3-Clause
66

7-
import "../exceptions.dart";
87
import "interaction_affordances/interaction_affordance.dart";
98

109
/// Enumeration for the possible WoT operation types.
@@ -55,7 +54,7 @@ enum OperationType {
5554
final operationType = OperationType._registry[stringValue];
5655

5756
if (operationType == null) {
58-
throw ValidationException(
57+
throw FormatException(
5958
"Encountered unknown OperationType $stringValue.",
6059
);
6160
}

lib/src/core/definitions/thing_description.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import "package:curie/curie.dart";
88
import "package:meta/meta.dart";
99

10-
import "../exceptions.dart";
1110
import "additional_expected_response.dart";
1211
import "context.dart";
1312
import "data_schema.dart";
@@ -60,7 +59,7 @@ class ThingDescription {
6059
if (validate) {
6160
final validationResult = thingDescriptionSchema.validate(json);
6261
if (!validationResult.isValid) {
63-
throw ValidationException(
62+
throw FormatException(
6463
"Validation of Thing Description failed.",
6564
validationResult.errors,
6665
);

lib/src/core/exceptions.dart

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ base class DartWotException implements Exception {
1414
/// Constructor.
1515
const DartWotException(this.message);
1616

17-
/// The error message of this [ValidationException].
17+
/// The error message of this [DartWotException].
1818
final String message;
1919

2020
/// The name of this [Exception] that will appear in the error message log.
@@ -24,34 +24,6 @@ base class DartWotException implements Exception {
2424
String toString() => "$exceptionType: $message";
2525
}
2626

27-
/// An [Exception] that is thrown when the validation of a definition fails.
28-
base class ValidationException extends DartWotException {
29-
/// Constructor.
30-
const ValidationException(super.message, [this._validationErrors]);
31-
32-
final List<Object>? _validationErrors;
33-
34-
@override
35-
String get exceptionType => "ValidationException";
36-
37-
@override
38-
String toString() {
39-
final String formattedValidationErrors;
40-
41-
final validationErrors = _validationErrors;
42-
if (validationErrors != null) {
43-
formattedValidationErrors = [
44-
"\n\nErrors:\n",
45-
...validationErrors,
46-
].join("\n");
47-
} else {
48-
formattedValidationErrors = "";
49-
}
50-
51-
return "$exceptionType: $message$formattedValidationErrors";
52-
}
53-
}
54-
5527
/// Custom [Exception] that is thrown when the discovery process fails.
5628
final class DiscoveryException extends DartWotException {
5729
/// Creates a new [DiscoveryException] with the specified error [message].

lib/src/core/implementation/augmented_form.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import "package:meta/meta.dart";
1010
import "package:uri/uri.dart";
1111

1212
import "../definitions.dart";
13-
import "../exceptions.dart";
1413

1514
/// A [Form] augmented with information from its associated [_thingDescription]
1615
/// and [_interactionAffordance].
@@ -140,7 +139,7 @@ final class AugmentedForm implements Form {
140139
.where((element) => !affordanceUriVariables.containsKey(element));
141140

142141
if (uncoveredHrefUriVariables.isNotEmpty) {
143-
throw ValidationException(
142+
throw FormatException(
144143
"The following URI template variables defined in the form's href "
145144
"but are not covered by a uriVariable entry at the TD or affordance "
146145
"level: ${uncoveredHrefUriVariables.join(", ")}.");
@@ -162,7 +161,7 @@ final class AugmentedForm implements Form {
162161
final result = schema.validate(userProvidedValue);
163162

164163
if (!result.isValid) {
165-
throw ValidationException("Invalid type for URI variable $key");
164+
throw FormatException("Invalid type for URI variable $key");
166165
}
167166
}
168167
}

lib/src/core/implementation/content_serdes.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import "package:http_parser/http_parser.dart";
1010
import "package:json_schema/json_schema.dart";
1111

1212
import "../definitions/data_schema.dart";
13-
import "../exceptions.dart";
1413
import "../scripting_api/data_schema_value.dart";
1514
import "codecs/cbor_codec.dart";
1615
import "codecs/codec_media_type.dart";
@@ -145,15 +144,15 @@ class ContentSerdes {
145144
}
146145

147146
if (dataSchemaValue == null) {
148-
throw const ValidationException("Expected a defined dataSchemaValue");
147+
throw const FormatException("Expected a defined dataSchemaValue");
149148
}
150149

151150
final schema = JsonSchema.create(
152151
Map.fromEntries(filteredDataSchemaJson),
153152
schemaVersion: SchemaVersion.draft7,
154153
);
155154
if (!schema.validate(dataSchemaValue.value).isValid) {
156-
throw const ValidationException("JSON Schema validation failed.");
155+
throw const FormatException("JSON Schema validation failed.");
157156
}
158157
}
159158

lib/src/core/implementation/thing_discovery.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ class ThingDiscovery extends Stream<ThingDescription>
409409
return dataSchemaValue.value.toThingDescription();
410410
}
411411

412-
throw ValidationException(
412+
throw FormatException(
413413
"Encountered wrong datatype ${dataSchemaValue.runtimeType} that cannot "
414414
"be processed as a Thing Description.",
415415
);

0 commit comments

Comments
 (0)