From f29113f6949a75c97e157df78aae2f0781d8308d Mon Sep 17 00:00:00 2001 From: Heshan Padmasiri Date: Tue, 15 Oct 2024 10:16:20 +0530 Subject: [PATCH 1/4] Add suggestions from previous PR Add suggestions from https://github.com/ballerina-platform/ballerina-distribution/pull/5709 --- .../check-expression/check_expression.bal | 1 + examples/error-reporting/error_reporting.bal | 2 ++ examples/error-subtyping/error_subtyping.bal | 4 +-- examples/error-subtyping/error_subtyping.md | 4 +-- .../error_type_intersection.bal | 28 +++++++------------ .../error_type_intersection.md | 2 +- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/examples/check-expression/check_expression.bal b/examples/check-expression/check_expression.bal index 6d68881fa4..cd634f73bb 100644 --- a/examples/check-expression/check_expression.bal +++ b/examples/check-expression/check_expression.bal @@ -1,5 +1,6 @@ import ballerina/io; +// Convert `bytes` to a `string` value and then to an `int` value. function intFromBytes(byte[] bytes) returns int|error { string|error res = string:fromBytes(bytes); // Explicitly check if the result is an error and diff --git a/examples/error-reporting/error_reporting.bal b/examples/error-reporting/error_reporting.bal index e85a2ff841..61c1270965 100644 --- a/examples/error-reporting/error_reporting.bal +++ b/examples/error-reporting/error_reporting.bal @@ -37,6 +37,8 @@ public function main() { {name: "Bob", age: -1}, {name: "Charlie", age: 30} ]; + // Note how the Person value after the value for which validation fails is + // not processed error? err = validatePeople(people); if err is error { printError(err); diff --git a/examples/error-subtyping/error_subtyping.bal b/examples/error-subtyping/error_subtyping.bal index 5cfb3623b2..26adf0c16b 100644 --- a/examples/error-subtyping/error_subtyping.bal +++ b/examples/error-subtyping/error_subtyping.bal @@ -12,7 +12,7 @@ type InvalidI32Detail record {| // Error with the `InvalidIntDetail` type as the detail type. type InvalidIntError error; -// `error` with `InvalidI32Detail` as the detail type. Thus it is a subtype of `InvalidIntError`. +// Error with `InvalidI32Detail` as the detail type. Thus it is a subtype of `InvalidIntError`. type InvalidI32Error error; // Distinct error with the `InvalidIntDetail` type as the detail type and a unique type ID. @@ -20,7 +20,7 @@ type InvalidI32Error error; // with `AnotherDistinctIntError` because they have different type IDs. type DistinctIntError distinct error; -// Another `error` with `InvalidIntDetail` as the detail type and different type ID to `DistinctIntError` +// Another distinct error with `InvalidIntDetail` as the detail type, but a different type ID to `DistinctIntError` // This is also a proper subtype of `InvalidIntError`, but doesn't have a subtype relationship with `DistinctIntError` type AnotherDistinctIntError distinct error; diff --git a/examples/error-subtyping/error_subtyping.md b/examples/error-subtyping/error_subtyping.md index 6cd53ee3a6..92f96f9408 100644 --- a/examples/error-subtyping/error_subtyping.md +++ b/examples/error-subtyping/error_subtyping.md @@ -1,8 +1,8 @@ # Error subtyping -If we want to identify if a given `error` type (say `ESub`) is a subtype of another error type (say `ESuper`), first we need to check if `ESuper` is a distinct error type. If it is not then `ESub` is a subtype if and only if the detail type of `ESub` is a subtype of the detail type of `ESuper`. +If we want to identify if a given `error` type (say `ESub`) is a subtype of another error type (say `ESuper`), first we need to check if `ESuper` is a distinct error type. If it is not, then `ESub` is a subtype if and only if the detail type of `ESub` is a subtype of the detail type of `ESuper`. -If more explicit control over error type relations is desired you can use `distinct` error types. Each declaration of a distinct error type has a unique type ID. If `ESuper` is a distinct error type there is the additional requirement that type ID of `ESub` must belong to the type ID set of `ESuper` for it to be a subtype. +If more explicit control over error type relations is desired you can use `distinct` error types. Each declaration of a distinct error type has a unique type ID. If `ESuper` is a distinct error type there is the additional requirement that the type ID set of `ESub` must contain all the type IDs of `ESuper`. In other words with distinct error types subtyping relationships behave similarly to nominal typing. Note that you can create subtypes of distinct error types by intersecting them with other error types. diff --git a/examples/error-type-intersection/error_type_intersection.bal b/examples/error-type-intersection/error_type_intersection.bal index 7049dcc62f..87edf2d606 100644 --- a/examples/error-type-intersection/error_type_intersection.bal +++ b/examples/error-type-intersection/error_type_intersection.bal @@ -12,36 +12,28 @@ type InputError error; type NumericError error; -type DistinctInputError distinct error; - -type DistinctNumericError distinct error; - // `NumericInputError` has detail type, `record {| int value |}`. type NumericInputError InputError & NumericError; -// `DistinctNumericInputError` has type ids of both `DistinctInputError` and `DistinctNumericError`. -type DistinctNumericInputError DistinctInputError & DistinctNumericError; +type DistinctInputError distinct error; -function createNumericInputError(int value) returns NumericInputError { - return error("Numeric input error", value = value); -} +type DistinctNumericError distinct error; -function createDistinctNumericInputError(int value) returns DistinctNumericInputError { - return error("Distinct numeric input error", value = value); -} +// `DistinctNumericInputError` has type IDs of both `DistinctInputError` and `DistinctNumericError`. +type DistinctNumericInputError DistinctInputError & DistinctNumericError; public function main() { - NumericInputError e1 = createNumericInputError(5); - // `e1` belong to `InputError` since its detail type is a subtype of `InputErrorDetail`. + NumericInputError e1 = error("Numeric input error", value = 5); + // `e1` belongs to `InputError` since its detail type is a subtype of `InputErrorDetail`. io:println(e1 is InputError); - // `e1` doesn't belong to `DistinctInputError` since it doesn't have the type id of `DistinctInputError`. + // `e1` doesn't belong to `DistinctInputError` since it doesn't have the type ID of `DistinctInputError`. io:println(e1 is DistinctInputError); - DistinctNumericInputError e2 = createDistinctNumericInputError(5); - // `e2` belong to `InputError` since it's detail type is a subtype of `InputErrorDetail`. + DistinctNumericInputError e2 = error("Distinct numeric input error", value = 5); + // `e2` belongs to `InputError` since its detail type is a subtype of `InputErrorDetail`. io:println(e2 is InputError); - // `e2` belong to `DistinctInputError` since it's type id set include the type id of `DistinctInputError`. + // `e2` belongs to `DistinctInputError` since its type ID set include the type id of `DistinctInputError`. io:println(e2 is DistinctInputError); } diff --git a/examples/error-type-intersection/error_type_intersection.md b/examples/error-type-intersection/error_type_intersection.md index 24b8631453..2e3c1bb58e 100644 --- a/examples/error-type-intersection/error_type_intersection.md +++ b/examples/error-type-intersection/error_type_intersection.md @@ -1,6 +1,6 @@ # Type intersection for error types -If you intersect two `error` types, the resulting type's detail type is the intersection of the detail types of both types. Furthermore, if any of the types being intersected is a distinct type, then the resultant type's type ID set includes all the type IDs of that type. Thus it is a subtype of both types and this is how you create subtypes of `distinct` error types. +If you intersect two `error` types, the resulting type's detail type is the intersection of the detail types of both types. Furthermore, if any of the types being intersected is a distinct type, then the resultant type's type ID set includes all the type IDs of that type. Thus it is a subtype of both types. This way, you can create an error type that is a subtype of multiple distinct types and also use a more specific detail type. ::: code error_type_intersection.bal ::: From 821eb2250a78ea74b9b050fe35754c8411a29397 Mon Sep 17 00:00:00 2001 From: Heshan Padmasiri Date: Tue, 15 Oct 2024 10:51:46 +0530 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Maryam Ziyad --- examples/error-reporting/error_reporting.bal | 4 ++-- examples/error-subtyping/error_subtyping.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/error-reporting/error_reporting.bal b/examples/error-reporting/error_reporting.bal index 61c1270965..22179d5b5c 100644 --- a/examples/error-reporting/error_reporting.bal +++ b/examples/error-reporting/error_reporting.bal @@ -37,8 +37,8 @@ public function main() { {name: "Bob", age: -1}, {name: "Charlie", age: 30} ]; - // Note how the Person value after the value for which validation fails is - // not processed + // Note how the `Person` value after the value for which validation fails is + // not processed. error? err = validatePeople(people); if err is error { printError(err); diff --git a/examples/error-subtyping/error_subtyping.md b/examples/error-subtyping/error_subtyping.md index 92f96f9408..a6c040dd78 100644 --- a/examples/error-subtyping/error_subtyping.md +++ b/examples/error-subtyping/error_subtyping.md @@ -2,7 +2,7 @@ If we want to identify if a given `error` type (say `ESub`) is a subtype of another error type (say `ESuper`), first we need to check if `ESuper` is a distinct error type. If it is not, then `ESub` is a subtype if and only if the detail type of `ESub` is a subtype of the detail type of `ESuper`. -If more explicit control over error type relations is desired you can use `distinct` error types. Each declaration of a distinct error type has a unique type ID. If `ESuper` is a distinct error type there is the additional requirement that the type ID set of `ESub` must contain all the type IDs of `ESuper`. In other words with distinct error types subtyping relationships behave similarly to nominal typing. +If more explicit control over error type relations is desired you can use `distinct` error types. Each declaration of a distinct error type has a unique type ID. If `ESuper` is a distinct error type there is the additional requirement that the type ID set of `ESub` must contain all the type IDs of `ESuper`. In other words, with distinct error types, typing relationships can be made more like nominal typing. Note that you can create subtypes of distinct error types by intersecting them with other error types. From 4a980f19611aa95fde1d6bbea8b70874cc3776d9 Mon Sep 17 00:00:00 2001 From: Heshan Padmasiri Date: Tue, 15 Oct 2024 11:34:52 +0530 Subject: [PATCH 3/4] Update examples/error-type-intersection/error_type_intersection.bal Co-authored-by: Maryam Ziyad --- examples/error-type-intersection/error_type_intersection.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/error-type-intersection/error_type_intersection.bal b/examples/error-type-intersection/error_type_intersection.bal index 87edf2d606..28733a1fd2 100644 --- a/examples/error-type-intersection/error_type_intersection.bal +++ b/examples/error-type-intersection/error_type_intersection.bal @@ -34,6 +34,6 @@ public function main() { // `e2` belongs to `InputError` since its detail type is a subtype of `InputErrorDetail`. io:println(e2 is InputError); - // `e2` belongs to `DistinctInputError` since its type ID set include the type id of `DistinctInputError`. + // `e2` belongs to `DistinctInputError` since its type ID set includes the type id of `DistinctInputError`. io:println(e2 is DistinctInputError); } From 02e2915489f8f27b7e6d864517f02dd6fd4b2c41 Mon Sep 17 00:00:00 2001 From: Heshan Padmasiri Date: Tue, 15 Oct 2024 12:44:35 +0530 Subject: [PATCH 4/4] Fix line numbers in output --- examples/error-reporting/error_reporting.out | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/error-reporting/error_reporting.out b/examples/error-reporting/error_reporting.out index 609403ab5e..1d4ad9acbc 100644 --- a/examples/error-reporting/error_reporting.out +++ b/examples/error-reporting/error_reporting.out @@ -3,8 +3,8 @@ Validating Alice Validating Bob Message: Validation failed for a person Detail: {"person":{"name":"Bob","age":-1}} -Stack trace: [callableName: validatePeople fileName: error_reporting.bal lineNumber: 20,callableName: main fileName: error_reporting.bal lineNumber: 40] +Stack trace: [callableName: validatePeople fileName: error_reporting.bal lineNumber: 20,callableName: main fileName: error_reporting.bal lineNumber: 42] Cause: Message: Age cannot be negative Detail: {"age":-1} -Stack trace: [callableName: validatePerson fileName: error_reporting.bal lineNumber: 30,callableName: validatePeople fileName: error_reporting.bal lineNumber: 16,callableName: main fileName: error_reporting.bal lineNumber: 40] +Stack trace: [callableName: validatePerson fileName: error_reporting.bal lineNumber: 30,callableName: validatePeople fileName: error_reporting.bal lineNumber: 16,callableName: main fileName: error_reporting.bal lineNumber: 42]