@@ -26,6 +26,14 @@ import Foundation
2626protocol Stage {
2727 var name : String { get }
2828 var bridge : StageBridge { get }
29+ /// The `errorMessage` defaults to `nil`. Errors during stage construction are captured and thrown later when `execute()` is called.
30+ var errorMessage : String ? { get }
31+ }
32+
33+ extension Stage {
34+ var errorMessage : String ? {
35+ return nil
36+ }
2937}
3038
3139@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
@@ -147,17 +155,19 @@ class AddFields: Stage {
147155 let name : String = " add_fields "
148156 let bridge : StageBridge
149157 private var selectables : [ Selectable ]
158+ let errorMessage : String ?
150159
151160 init ( selectables: [ Selectable ] ) {
152161 self . selectables = selectables
153- let objc_accumulators = selectables. reduce ( into: [ String: ExprBridge] ( ) ) {
154- result,
155- selectable
156- in
157- let selectableWrapper = selectable as! SelectableWrapper
158- result [ selectableWrapper. alias] = selectableWrapper. expr. toBridge ( )
162+ let ( map, error) = Helper . selectablesToMap ( selectables: selectables)
163+ if let error = error {
164+ errorMessage = error. localizedDescription
165+ bridge = AddFieldsStageBridge ( fields: [ : ] )
166+ } else {
167+ errorMessage = nil
168+ let objcAccumulators = map. mapValues { $0. toBridge ( ) }
169+ bridge = AddFieldsStageBridge ( fields: objcAccumulators)
159170 }
160- bridge = AddFieldsStageBridge ( fields: objc_accumulators)
161171 }
162172}
163173
@@ -182,23 +192,37 @@ class RemoveFieldsStage: Stage {
182192class Select : Stage {
183193 let name : String = " select "
184194 let bridge : StageBridge
195+ let errorMessage : String ?
185196
186197 init ( selections: [ Selectable ] ) {
187- let map = Helper . selectablesToMap ( selectables: selections)
188- bridge = SelectStageBridge ( selections: map
189- . mapValues { Helper . sendableToExpr ( $0) . toBridge ( ) } )
198+ let ( map, error) = Helper . selectablesToMap ( selectables: selections)
199+ if let error = error {
200+ errorMessage = error. localizedDescription
201+ bridge = SelectStageBridge ( selections: [ : ] )
202+ } else {
203+ errorMessage = nil
204+ let objcSelections = map. mapValues { Helper . sendableToExpr ( $0) . toBridge ( ) }
205+ bridge = SelectStageBridge ( selections: objcSelections)
206+ }
190207 }
191208}
192209
193210@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
194211class Distinct : Stage {
195212 let name : String = " distinct "
196213 let bridge : StageBridge
214+ let errorMessage : String ?
197215
198216 init ( groups: [ Selectable ] ) {
199- let map = Helper . selectablesToMap ( selectables: groups)
200- bridge = DistinctStageBridge ( groups: map
201- . mapValues { Helper . sendableToExpr ( $0) . toBridge ( ) } )
217+ let ( map, error) = Helper . selectablesToMap ( selectables: groups)
218+ if let error = error {
219+ errorMessage = error. localizedDescription
220+ bridge = DistinctStageBridge ( groups: [ : ] )
221+ } else {
222+ errorMessage = nil
223+ let objcGroups = map. mapValues { Helper . sendableToExpr ( $0) . toBridge ( ) }
224+ bridge = DistinctStageBridge ( groups: objcGroups)
225+ }
202226 }
203227}
204228
@@ -208,18 +232,32 @@ class Aggregate: Stage {
208232 let bridge : StageBridge
209233 private var accumulators : [ AliasedAggregate ]
210234 private var groups : [ String : Expression ] = [ : ]
235+ let errorMessage : String ?
211236
212237 init ( accumulators: [ AliasedAggregate ] , groups: [ Selectable ] ? ) {
213238 self . accumulators = accumulators
214- if groups != nil {
215- self . groups = Helper . selectablesToMap ( selectables: groups!)
216- }
217- let accumulatorsMap = accumulators
218- . reduce ( into: [ String: AggregateFunctionBridge] ( ) ) { result, accumulator in
219- result [ accumulator. alias] = accumulator. aggregate. bridge
239+
240+ if let groups = groups {
241+ let ( map, error) = Helper . selectablesToMap ( selectables: groups)
242+ if let error = error {
243+ errorMessage = error. localizedDescription
244+ bridge = AggregateStageBridge ( accumulators: [ : ] , groups: [ : ] )
245+ return
220246 }
247+ self . groups = map
248+ }
249+
250+ let ( accumulatorsMap, error) = Helper . aliasedAggregatesToMap ( accumulators: accumulators)
251+ if let error = error {
252+ errorMessage = error. localizedDescription
253+ bridge = AggregateStageBridge ( accumulators: [ : ] , groups: [ : ] )
254+ return
255+ }
256+
257+ errorMessage = nil
258+ let accumulatorBridgesMap = accumulatorsMap. mapValues { $0. bridge }
221259 bridge = AggregateStageBridge (
222- accumulators: accumulatorsMap ,
260+ accumulators: accumulatorBridgesMap ,
223261 groups: self . groups. mapValues { Helper . sendableToExpr ( $0) . toBridge ( ) }
224262 )
225263 }
0 commit comments