@@ -19,16 +19,21 @@ class SwiftOptions {
19
19
/// Creates a [SwiftOptions] object
20
20
const SwiftOptions ({
21
21
this .copyrightHeader,
22
+ this .errorClassName,
22
23
});
23
24
24
25
/// A copyright header that will get prepended to generated code.
25
26
final Iterable <String >? copyrightHeader;
26
27
28
+ /// The name of the error class used for passing custom error parameters.
29
+ final String ? errorClassName;
30
+
27
31
/// Creates a [SwiftOptions] from a Map representation where:
28
32
/// `x = SwiftOptions.fromList(x.toMap())` .
29
33
static SwiftOptions fromList (Map <String , Object > map) {
30
34
return SwiftOptions (
31
35
copyrightHeader: map['copyrightHeader' ] as Iterable <String >? ,
36
+ errorClassName: map['errorClassName' ] as String ? ,
32
37
);
33
38
}
34
39
@@ -37,6 +42,7 @@ class SwiftOptions {
37
42
Map <String , Object > toMap () {
38
43
final Map <String , Object > result = < String , Object > {
39
44
if (copyrightHeader != null ) 'copyrightHeader' : copyrightHeader! ,
45
+ if (errorClassName != null ) 'errorClassName' : errorClassName! ,
40
46
};
41
47
return result;
42
48
}
@@ -316,7 +322,7 @@ class SwiftGenerator extends StructuredGenerator<SwiftOptions> {
316
322
name: func.name,
317
323
parameters: func.parameters,
318
324
returnType: func.returnType,
319
- errorTypeName: 'FlutterError' ,
325
+ errorTypeName: _getErrorClassName (generatorOptions) ,
320
326
isAsynchronous: true ,
321
327
swiftFunction: func.swiftFunction,
322
328
getParameterName: _getSafeArgumentName,
@@ -350,6 +356,7 @@ class SwiftGenerator extends StructuredGenerator<SwiftOptions> {
350
356
indent, func.documentationComments, _docCommentSpec);
351
357
_writeFlutterMethod (
352
358
indent,
359
+ generatorOptions: generatorOptions,
353
360
name: func.name,
354
361
channelName: makeChannelName (api, func, dartPackageName),
355
362
parameters: func.parameters,
@@ -614,10 +621,20 @@ class SwiftGenerator extends StructuredGenerator<SwiftOptions> {
614
621
});
615
622
}
616
623
617
- void _writeWrapError (Indent indent) {
624
+ void _writeWrapError (SwiftOptions generatorOptions, Indent indent) {
618
625
indent.newln ();
619
626
indent.write ('private func wrapError(_ error: Any) -> [Any?] ' );
620
627
indent.addScoped ('{' , '}' , () {
628
+ indent.write (
629
+ 'if let pigeonError = error as? ${_getErrorClassName (generatorOptions )} ' );
630
+ indent.addScoped ('{' , '}' , () {
631
+ indent.write ('return ' );
632
+ indent.addScoped ('[' , ']' , () {
633
+ indent.writeln ('pigeonError.code,' );
634
+ indent.writeln ('pigeonError.message,' );
635
+ indent.writeln ('pigeonError.details,' );
636
+ });
637
+ });
621
638
indent.write ('if let flutterError = error as? FlutterError ' );
622
639
indent.addScoped ('{' , '}' , () {
623
640
indent.write ('return ' );
@@ -645,13 +662,14 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
645
662
}''' );
646
663
}
647
664
648
- void _writeCreateConnectionError (Indent indent) {
665
+ void _writeCreateConnectionError (
666
+ SwiftOptions generatorOptions, Indent indent) {
649
667
indent.newln ();
650
668
indent.writeScoped (
651
- 'private func createConnectionError(withChannelName channelName: String) -> FlutterError {' ,
669
+ 'private func createConnectionError(withChannelName channelName: String) -> ${ _getErrorClassName ( generatorOptions )} {' ,
652
670
'}' , () {
653
671
indent.writeln (
654
- 'return FlutterError (code: "channel-error", message: "Unable to establish connection on channel: \'\\ (channelName)\' .", details: "")' );
672
+ 'return ${ _getErrorClassName ( generatorOptions )} (code: "channel-error", message: "Unable to establish connection on channel: \'\\ (channelName)\' .", details: "")' );
655
673
});
656
674
}
657
675
@@ -669,19 +687,23 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
669
687
.whereType <AstFlutterApi >()
670
688
.any ((Api api) => api.methods.isNotEmpty);
671
689
690
+ _writePigeonError (generatorOptions, indent);
691
+
672
692
if (hasHostApi) {
673
693
_writeWrapResult (indent);
674
- _writeWrapError (indent);
694
+ _writeWrapError (generatorOptions, indent);
675
695
}
676
696
if (hasFlutterApi) {
677
- _writeCreateConnectionError (indent);
697
+ _writeCreateConnectionError (generatorOptions, indent);
678
698
}
699
+
679
700
_writeIsNullish (indent);
680
701
_writeNilOrValue (indent);
681
702
}
682
703
683
704
void _writeFlutterMethod (
684
705
Indent indent, {
706
+ required SwiftOptions generatorOptions,
685
707
required String name,
686
708
required String channelName,
687
709
required List <Parameter > parameters,
@@ -693,7 +715,7 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
693
715
name: name,
694
716
parameters: parameters,
695
717
returnType: returnType,
696
- errorTypeName: 'FlutterError' ,
718
+ errorTypeName: _getErrorClassName (generatorOptions) ,
697
719
isAsynchronous: true ,
698
720
swiftFunction: swiftFunction,
699
721
getParameterName: _getSafeArgumentName,
@@ -735,12 +757,12 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
735
757
indent.writeln ('let message: String? = nilOrValue(listResponse[1])' );
736
758
indent.writeln ('let details: String? = nilOrValue(listResponse[2])' );
737
759
indent.writeln (
738
- 'completion(.failure(FlutterError (code: code, message: message, details: details)))' );
760
+ 'completion(.failure(${ _getErrorClassName ( generatorOptions )} (code: code, message: message, details: details)))' );
739
761
}, addTrailingNewline: false );
740
762
if (! returnType.isNullable && ! returnType.isVoid) {
741
763
indent.addScoped ('else if listResponse[0] == nil {' , '} ' , () {
742
764
indent.writeln (
743
- 'completion(.failure(FlutterError (code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))' );
765
+ 'completion(.failure(${ _getErrorClassName ( generatorOptions )} (code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))' );
744
766
}, addTrailingNewline: false );
745
767
}
746
768
indent.addScoped ('else {' , '}' , () {
@@ -870,11 +892,41 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
870
892
indent.writeln ('$varChannelName .setMessageHandler(nil)' );
871
893
});
872
894
}
895
+
896
+ void _writePigeonError (SwiftOptions generatorOptions, Indent indent) {
897
+ indent.newln ();
898
+ indent.writeln (
899
+ '/// Error class for passing custom error details to Dart side.' );
900
+ indent.writeScoped (
901
+ 'final class ${_getErrorClassName (generatorOptions )}: Error {' , '}' ,
902
+ () {
903
+ indent.writeln ('let code: String' );
904
+ indent.writeln ('let message: String?' );
905
+ indent.writeln ('let details: Any?' );
906
+ indent.newln ();
907
+ indent.writeScoped (
908
+ 'init(code: String, message: String?, details: Any?) {' , '}' , () {
909
+ indent.writeln ('self.code = code' );
910
+ indent.writeln ('self.message = message' );
911
+ indent.writeln ('self.details = details' );
912
+ });
913
+ indent.newln ();
914
+ indent.writeScoped ('var localizedDescription: String {' , '}' , () {
915
+ indent.writeScoped ('return' , '' , () {
916
+ indent.writeln (
917
+ '"${_getErrorClassName (generatorOptions )}(code: \\ (code), message: \\ (message ?? "<nil>"), details: \\ (details ?? "<nil>")"' );
918
+ }, addTrailingNewline: false );
919
+ });
920
+ });
921
+ }
873
922
}
874
923
875
924
/// Calculates the name of the codec that will be generated for [api] .
876
925
String _getCodecName (Api api) => '${api .name }Codec' ;
877
926
927
+ String _getErrorClassName (SwiftOptions generatorOptions) =>
928
+ generatorOptions.errorClassName ?? 'PigeonError' ;
929
+
878
930
String _getArgumentName (int count, NamedType argument) =>
879
931
argument.name.isEmpty ? 'arg$count ' : argument.name;
880
932
0 commit comments