@@ -49,6 +49,11 @@ describe('AsyncWriter', () => {
49
49
return Object . assign (
50
50
Promise . resolve ( implicitlyAsyncValue ) ,
51
51
{ [ Symbol . for ( '@@mongosh.syntheticPromise' ) ] : true } ) ;
52
+ } ,
53
+ throwUncatchable ( ) {
54
+ throw Object . assign (
55
+ new Error ( 'uncatchable!' ) ,
56
+ { [ Symbol . for ( '@@mongosh.uncatchable' ) ] : true } ) ;
52
57
}
53
58
} ) ;
54
59
runTranspiledCode = ( code : string , context ?: any ) => {
@@ -760,4 +765,182 @@ describe('AsyncWriter', () => {
760
765
} ) ;
761
766
} ) ;
762
767
} ) ;
768
+
769
+ context ( 'uncatchable exceptions' , ( ) => {
770
+ it ( 'allows catching regular exceptions' , ( ) => {
771
+ const result = runTranspiledCode ( `
772
+ (() => {
773
+ try {
774
+ throw new Error('generic error');
775
+ } catch (err) {
776
+ return ({ caught: err });
777
+ }
778
+ })();` ) ;
779
+ expect ( result . caught . message ) . to . equal ( 'generic error' ) ;
780
+ } ) ;
781
+
782
+ it ( 'allows catching regular exceptions with destructuring catch (object)' , ( ) => {
783
+ const result = runTranspiledCode ( `
784
+ (() => {
785
+ try {
786
+ throw new Error('generic error');
787
+ } catch ({ message }) {
788
+ return ({ caught: message });
789
+ }
790
+ })();` ) ;
791
+ expect ( result . caught ) . to . equal ( 'generic error' ) ;
792
+ } ) ;
793
+
794
+
795
+ it ( 'allows catching regular exceptions with destructuring catch (array)' , ( ) => {
796
+ const result = runTranspiledCode ( `
797
+ (() => {
798
+ try {
799
+ throw [ 'foo' ];
800
+ } catch ([message]) {
801
+ return ({ caught: message });
802
+ }
803
+ })();` ) ;
804
+ expect ( result . caught ) . to . equal ( 'foo' ) ;
805
+ } ) ;
806
+
807
+ it ( 'allows catching regular exceptions with destructuring catch (assignable)' , ( ) => {
808
+ const result = runTranspiledCode ( `
809
+ (() => {
810
+ try {
811
+ throw [ 'foo' ];
812
+ } catch ([message]) {
813
+ message = 42;
814
+ return ({ caught: message });
815
+ }
816
+ })();` ) ;
817
+ expect ( result . caught ) . to . equal ( 42 ) ;
818
+ } ) ;
819
+
820
+ it ( 'allows rethrowing regular exceptions' , ( ) => {
821
+ try {
822
+ runTranspiledCode ( `
823
+ (() => {
824
+ try {
825
+ throw new Error('generic error');
826
+ } catch (err) {
827
+ throw err;
828
+ }
829
+ })();` ) ;
830
+ expect . fail ( 'missed exception' ) ;
831
+ } catch ( err ) {
832
+ expect ( err . message ) . to . equal ( 'generic error' ) ;
833
+ }
834
+ } ) ;
835
+
836
+ it ( 'allows returning from finally' , ( ) => {
837
+ const result = runTranspiledCode ( `
838
+ (() => {
839
+ try {
840
+ throw new Error('generic error');
841
+ } catch (err) {
842
+ return ({ caught: err });
843
+ } finally {
844
+ return 'finally';
845
+ }
846
+ })();` ) ;
847
+ expect ( result ) . to . equal ( 'finally' ) ;
848
+ } ) ;
849
+
850
+ it ( 'allows finally without catch' , ( ) => {
851
+ const result = runTranspiledCode ( `
852
+ (() => {
853
+ try {
854
+ throw new Error('generic error');
855
+ } finally {
856
+ return 'finally';
857
+ }
858
+ })();` ) ;
859
+ expect ( result ) . to . equal ( 'finally' ) ;
860
+ } ) ;
861
+
862
+ it ( 'allows throwing primitives' , ( ) => {
863
+ const result = runTranspiledCode ( `
864
+ (() => {
865
+ try {
866
+ throw null;
867
+ } catch (err) {
868
+ return ({ caught: err });
869
+ }
870
+ })();` ) ;
871
+ expect ( result . caught ) . to . equal ( null ) ;
872
+ } ) ;
873
+
874
+ it ( 'allows throwing primitives with finally' , ( ) => {
875
+ const result = runTranspiledCode ( `
876
+ (() => {
877
+ try {
878
+ throw null;
879
+ } catch (err) {
880
+ return ({ caught: err });
881
+ } finally {
882
+ return 'finally';
883
+ }
884
+ })();` ) ;
885
+ expect ( result ) . to . equal ( 'finally' ) ;
886
+ } ) ;
887
+
888
+ it ( 'does not catch uncatchable exceptions' , ( ) => {
889
+ try {
890
+ runTranspiledCode ( `
891
+ (() => {
892
+ try {
893
+ throwUncatchable();
894
+ } catch (err) {
895
+ return ({ caught: err });
896
+ }
897
+ })();` ) ;
898
+ expect . fail ( 'missed exception' ) ;
899
+ } catch ( err ) {
900
+ expect ( err . message ) . to . equal ( 'uncatchable!' ) ;
901
+ }
902
+ } ) ;
903
+
904
+ it ( 'does not catch uncatchable exceptions with empty catch clause' , ( ) => {
905
+ try {
906
+ runTranspiledCode ( `
907
+ (() => {
908
+ try {
909
+ throwUncatchable();
910
+ } catch { }
911
+ })();` ) ;
912
+ expect . fail ( 'missed exception' ) ;
913
+ } catch ( err ) {
914
+ expect ( err . message ) . to . equal ( 'uncatchable!' ) ;
915
+ }
916
+ } ) ;
917
+
918
+ it ( 'does not catch uncatchable exceptions with finalizer' , ( ) => {
919
+ try {
920
+ runTranspiledCode ( `
921
+ (() => {
922
+ try {
923
+ throwUncatchable();
924
+ } catch { } finally { return; }
925
+ })();` ) ;
926
+ expect . fail ( 'missed exception' ) ;
927
+ } catch ( err ) {
928
+ expect ( err . message ) . to . equal ( 'uncatchable!' ) ;
929
+ }
930
+ } ) ;
931
+
932
+ it ( 'does not catch uncatchable exceptions with only finalizer' , ( ) => {
933
+ try {
934
+ runTranspiledCode ( `
935
+ (() => {
936
+ try {
937
+ throwUncatchable();
938
+ } finally { return; }
939
+ })();` ) ;
940
+ expect . fail ( 'missed exception' ) ;
941
+ } catch ( err ) {
942
+ expect ( err . message ) . to . equal ( 'uncatchable!' ) ;
943
+ }
944
+ } ) ;
945
+ } ) ;
763
946
} ) ;
0 commit comments