@@ -8,12 +8,16 @@ import 'dart:core' hide UnimplementedError;
88import 'package:celest_core/src/exception/celest_exception.dart' ;
99import 'package:celest_core/src/http/http_error.dart' ;
1010import 'package:celest_core/src/http/http_status.dart' ;
11+ import 'package:celest_core/src/proto/google/protobuf/struct.pb.dart' ;
1112import 'package:celest_core/src/serialization/json_value.dart' ;
1213import 'package:celest_core/src/util/json.dart' ;
1314import 'package:grpc/grpc_or_grpcweb.dart' show StatusCode, GrpcError;
1415import 'package:http/http.dart' as http show Response;
1516import 'package:json_annotation/json_annotation.dart' show JsonKey;
1617import 'package:meta/meta.dart' ;
18+ import 'package:protobuf/protobuf.dart' ;
19+ import 'package:protobuf/src/protobuf/json_parsing_context.dart' ;
20+ import 'package:protobuf/src/protobuf/mixins/well_known.dart' ;
1721
1822/// An exception thrown by a Cloud Widget.
1923abstract mixin class CloudException implements CelestException {
@@ -150,82 +154,66 @@ abstract mixin class CloudException implements CelestException {
150154 StatusCode .aborted => AbortedException .of (
151155 message: message,
152156 details: details,
153- code: code,
154157 ),
155158 StatusCode .alreadyExists => AlreadyExistsException .of (
156159 message: message,
157160 details: details,
158- code: code,
159161 ),
160162 StatusCode .cancelled => CancelledException .of (
161163 message: message,
162164 details: details,
163- code: code,
164165 ),
165166 StatusCode .dataLoss => DataLossError .of (
166167 message: message,
167168 details: details,
168- code: code,
169169 ),
170170 StatusCode .deadlineExceeded => DeadlineExceededError .of (
171171 message: message,
172172 details: details,
173- code: code,
174173 ),
175174 StatusCode .failedPrecondition => FailedPreconditionException .of (
176175 message: message,
177176 details: details,
178- code: code,
179177 ),
180178 StatusCode .internal => InternalServerError .of (
181179 message: message,
182180 details: details,
183- code: code,
184181 ),
185182 StatusCode .invalidArgument => BadRequestException .of (
186183 message: message,
187184 details: details,
188- code: code,
189185 ),
190186 StatusCode .notFound => NotFoundException .of (
191187 message: message,
192188 details: details,
193- code: code,
194189 ),
195190 StatusCode .outOfRange => OutOfRangeException .of (
196191 message: message,
197192 details: details,
198- code: code,
199193 ),
200194 StatusCode .permissionDenied => PermissionDeniedException .of (
201195 message: message,
202196 details: details,
203- code: code,
204197 ),
205198 StatusCode .resourceExhausted => ResourceExhaustedException .of (
206199 message: message,
207200 details: details,
208- code: code,
209201 ),
210202 StatusCode .unauthenticated => UnauthorizedException .of (
211203 message: message,
212204 details: details,
213- code: code,
214205 ),
215206 StatusCode .unavailable => UnavailableError .of (
216207 message: message,
217208 details: details,
218- code: code,
219209 ),
220210 StatusCode .unimplemented => UnimplementedError .of (
221211 message: message,
222212 details: details,
223- code: code,
224213 ),
225214 _ => UnknownError .of (
226215 message: message,
227216 details: details,
228- code: code,
229217 ),
230218 };
231219 }
@@ -380,12 +368,44 @@ abstract mixin class CloudException implements CelestException {
380368 /// The code associated with the exception.
381369 int get code;
382370
371+ /// The gRPC status associated with the exception.
372+ int get grpcStatus => StatusCode .unknown;
373+
374+ /// The HTTP status associated with the exception.
375+ HttpStatus get httpStatus;
376+
383377 @override
384378 String get message;
385379
386380 /// Any details associated with the exception.
387381 JsonValue ? get details;
388382
383+ /// Converts the exception to a gRPC error.
384+ GrpcError toGrpcError () {
385+ GeneratedMessage convert (Object ? o) {
386+ final value = Value ();
387+ ValueMixin .fromProto3JsonHelper (
388+ value,
389+ o,
390+ const TypeRegistry .empty (),
391+ JsonParsingContext (false , false , false ),
392+ );
393+ return value;
394+ }
395+
396+ return GrpcError .custom (
397+ grpcStatus,
398+ message,
399+ switch (details) {
400+ null => null ,
401+ final JsonList list => [
402+ for (final value in list) convert (value),
403+ ],
404+ final JsonValue value => [convert (value)],
405+ },
406+ );
407+ }
408+
389409 @override
390410 String toString () {
391411 final buf = StringBuffer ('$runtimeType : $message ' );
@@ -428,6 +448,12 @@ class CancelledException with CloudException {
428448
429449 @override
430450 final JsonValue ? details;
451+
452+ @override
453+ int get grpcStatus => StatusCode .cancelled;
454+
455+ @override
456+ HttpStatus get httpStatus => HttpStatus .clientClosedRequest;
431457}
432458
433459/// {@template celest_core.exception.unknown_error}
@@ -459,6 +485,12 @@ class UnknownError extends Error with CloudException {
459485
460486 @override
461487 final JsonValue ? details;
488+
489+ @override
490+ int get grpcStatus => StatusCode .unknown;
491+
492+ @override
493+ HttpStatus get httpStatus => HttpStatus .internalServerError;
462494}
463495
464496/// {@template celest_core.exception.bad_request_exception}
@@ -502,6 +534,12 @@ abstract base class BadRequestException extends CloudException {
502534
503535 @override
504536 final JsonValue ? details;
537+
538+ @override
539+ int get grpcStatus => StatusCode .invalidArgument;
540+
541+ @override
542+ HttpStatus get httpStatus => HttpStatus .badRequest;
505543}
506544
507545final class _BadRequestException extends BadRequestException {
@@ -544,6 +582,12 @@ class UnauthorizedException with CloudException {
544582
545583 @override
546584 final JsonValue ? details;
585+
586+ @override
587+ int get grpcStatus => StatusCode .unauthenticated;
588+
589+ @override
590+ HttpStatus get httpStatus => HttpStatus .unauthorized;
547591}
548592
549593/// {@template celest_core.exception.not_found_exception}
@@ -576,6 +620,12 @@ class NotFoundException with CloudException {
576620
577621 @override
578622 final JsonValue ? details;
623+
624+ @override
625+ int get grpcStatus => StatusCode .notFound;
626+
627+ @override
628+ HttpStatus get httpStatus => HttpStatus .notFound;
579629}
580630
581631/// {@template celest_core.exception.already_exists_exception}
@@ -607,6 +657,12 @@ class AlreadyExistsException with CloudException {
607657
608658 @override
609659 final JsonValue ? details;
660+
661+ @override
662+ int get grpcStatus => StatusCode .alreadyExists;
663+
664+ @override
665+ HttpStatus get httpStatus => HttpStatus .conflict;
610666}
611667
612668/// {@template celest_core.exception.permission_denied_exception}
@@ -642,6 +698,12 @@ class PermissionDeniedException with CloudException {
642698
643699 @override
644700 final JsonValue ? details;
701+
702+ @override
703+ int get grpcStatus => StatusCode .permissionDenied;
704+
705+ @override
706+ HttpStatus get httpStatus => HttpStatus .forbidden;
645707}
646708
647709/// {@template celest_core.exception.resource_exhausted_exception}
@@ -676,6 +738,12 @@ class ResourceExhaustedException with CloudException {
676738
677739 @override
678740 final JsonValue ? details;
741+
742+ @override
743+ int get grpcStatus => StatusCode .resourceExhausted;
744+
745+ @override
746+ HttpStatus get httpStatus => HttpStatus .tooManyRequests;
679747}
680748
681749/// {@template celest_core.exception.failed_precondition_exception}
@@ -711,6 +779,12 @@ class FailedPreconditionException with CloudException {
711779
712780 @override
713781 final JsonValue ? details;
782+
783+ @override
784+ int get grpcStatus => StatusCode .failedPrecondition;
785+
786+ @override
787+ HttpStatus get httpStatus => HttpStatus .preconditionFailed;
714788}
715789
716790/// {@template celest_core.exception.aborted_exception}
@@ -742,6 +816,12 @@ class AbortedException with CloudException {
742816
743817 @override
744818 final JsonValue ? details;
819+
820+ @override
821+ int get grpcStatus => StatusCode .aborted;
822+
823+ @override
824+ HttpStatus get httpStatus => HttpStatus .conflict;
745825}
746826
747827/// {@template celest_core.exception.out_of_range_exception}
@@ -773,6 +853,12 @@ class OutOfRangeException with CloudException {
773853
774854 @override
775855 final JsonValue ? details;
856+
857+ @override
858+ int get grpcStatus => StatusCode .outOfRange;
859+
860+ @override
861+ HttpStatus get httpStatus => HttpStatus .requestedRangeNotSatisfiable;
776862}
777863
778864/// {@template celest_core.exception.unimplemented_error}
@@ -804,6 +890,12 @@ class UnimplementedError extends core.UnimplementedError with CloudException {
804890
805891 @override
806892 final JsonValue ? details;
893+
894+ @override
895+ int get grpcStatus => StatusCode .unimplemented;
896+
897+ @override
898+ HttpStatus get httpStatus => HttpStatus .notImplemented;
807899}
808900
809901/// {@template celest_core.exception.internal_server_error}
@@ -836,6 +928,12 @@ class InternalServerError extends Error with CloudException {
836928
837929 @override
838930 final JsonValue ? details;
931+
932+ @override
933+ int get grpcStatus => StatusCode .internal;
934+
935+ @override
936+ HttpStatus get httpStatus => HttpStatus .internalServerError;
839937}
840938
841939/// {@template celest_core.exception.unavailable_error}
@@ -867,6 +965,12 @@ class UnavailableError extends Error with CloudException {
867965
868966 @override
869967 final JsonValue ? details;
968+
969+ @override
970+ int get grpcStatus => StatusCode .unavailable;
971+
972+ @override
973+ HttpStatus get httpStatus => HttpStatus .serviceUnavailable;
870974}
871975
872976/// {@template celest_core.exception.data_loss_error}
@@ -898,6 +1002,12 @@ class DataLossError extends Error with CloudException {
8981002
8991003 @override
9001004 final JsonValue ? details;
1005+
1006+ @override
1007+ int get grpcStatus => StatusCode .dataLoss;
1008+
1009+ @override
1010+ HttpStatus get httpStatus => HttpStatus .internalServerError;
9011011}
9021012
9031013/// {@template celest_core.exception.deadline_exceeded_error}
@@ -929,4 +1039,10 @@ class DeadlineExceededError extends Error with CloudException {
9291039
9301040 @override
9311041 final JsonValue ? details;
1042+
1043+ @override
1044+ int get grpcStatus => StatusCode .deadlineExceeded;
1045+
1046+ @override
1047+ HttpStatus get httpStatus => HttpStatus .gatewayTimeout;
9321048}
0 commit comments