@@ -92,6 +92,7 @@ use isolate::{
9292 ConcurrencyLimiter ,
9393 FunctionOutcome ,
9494 FunctionResult ,
95+ HttpActionOutcome ,
9596 HttpActionRequest ,
9697 IsolateClient ,
9798 IsolateConfig ,
@@ -813,16 +814,15 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
813814 let ( mut tx, mut outcome) = match result {
814815 Ok ( r) => r,
815816 Err ( e) => {
816- self . log_udf_system_error (
817+ self . function_log . log_mutation_system_error (
818+ & e,
817819 udf_path,
818820 arguments,
819821 identity,
820822 start,
821823 caller,
822- & e,
823824 context. clone ( ) ,
824- )
825- . await ?;
825+ ) ;
826826 return Err ( e) ;
827827 } ,
828828 } ;
@@ -847,7 +847,6 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
847847 stats,
848848 execution_time,
849849 caller,
850- false ,
851850 usage_tracker,
852851 context. clone ( ) ,
853852 ) ;
@@ -903,13 +902,11 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
903902 }
904903 outcome. result = Err ( JsError :: from_error_ref ( & e) ) ;
905904
906- self . function_log . log_mutation (
907- outcome. clone ( ) ,
905+ self . function_log . log_mutation_occ_error (
906+ outcome,
908907 stats,
909908 execution_time,
910909 caller,
911- true ,
912- usage_tracker,
913910 context. clone ( ) ,
914911 ) ;
915912 log_occ_retries ( backoff. failures ( ) as usize ) ;
@@ -923,7 +920,6 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
923920 stats,
924921 execution_time,
925922 caller,
926- false ,
927923 usage_tracker,
928924 context. clone ( ) ,
929925 ) ;
@@ -1046,22 +1042,38 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
10461042 let context = ExecutionContext :: new ( request_id. clone ( ) , & caller) ;
10471043 let name = name. canonicalize ( ) ;
10481044 let usage_tracking = FunctionUsageTracker :: new ( ) ;
1049- let completion = self
1045+ let start = self . runtime . monotonic_now ( ) ;
1046+ let completion_result = self
10501047 . run_action_no_udf_log (
1051- name,
1052- arguments,
1048+ name. clone ( ) ,
1049+ arguments. clone ( ) ,
10531050 identity. clone ( ) ,
10541051 allowed_visibility,
1055- caller,
1052+ caller. clone ( ) ,
10561053 usage_tracking. clone ( ) ,
1057- context,
1054+ context. clone ( ) ,
10581055 )
1059- . await ?;
1056+ . await ;
1057+ let completion = match completion_result {
1058+ Ok ( c) => c,
1059+ Err ( e) => {
1060+ self . function_log . log_action_system_error (
1061+ & e,
1062+ name,
1063+ arguments,
1064+ identity. into ( ) ,
1065+ start,
1066+ caller,
1067+ vec ! [ ] . into ( ) ,
1068+ context,
1069+ ) ;
1070+ anyhow:: bail!( e)
1071+ } ,
1072+ } ;
10601073 let log_lines =
10611074 RedactedLogLines :: from_log_lines ( completion. log_lines ( ) . clone ( ) , block_logging) ;
10621075 let result = completion. outcome . result . clone ( ) ;
1063- self . function_log
1064- . log_action ( completion, false , usage_tracking) ;
1076+ self . function_log . log_action ( completion, usage_tracking) ;
10651077
10661078 let value = match result {
10671079 Ok ( ref value) => value. unpack ( ) ,
@@ -1173,6 +1185,7 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
11731185 } ) ;
11741186 } ,
11751187 } ;
1188+ let udf_server_version = path_and_args. npm_version ( ) . clone ( ) ;
11761189 // We should not be missing the module given we validated the path above
11771190 // which requires the module to exist.
11781191 let module_version = self
@@ -1182,8 +1195,9 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
11821195 . context ( "Missing a valid module_version" ) ?;
11831196 let ( log_line_sender, log_line_receiver) = mpsc:: unbounded ( ) ;
11841197
1198+ let inert_identity = tx. inert_identity ( ) ;
11851199 let timer = function_total_timer ( module_version. environment , UdfType :: Action ) ;
1186- match module_version. environment {
1200+ let completion_result = match module_version. environment {
11871201 ModuleEnvironment :: Isolate => {
11881202 // TODO: This is the only use case of clone. We should get rid of clone,
11891203 // when we deprecate that codepath.
@@ -1205,19 +1219,18 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
12051219 } ,
12061220 )
12071221 . await ;
1208- let outcome = outcome_result?;
12091222 let memory_in_mb: u64 = ( * ISOLATE_MAX_USER_HEAP_SIZE / ( 1 << 20 ) )
12101223 . try_into ( )
12111224 . unwrap ( ) ;
12121225 timer. finish ( ) ;
1213- Ok ( ActionCompletion {
1226+ outcome_result . map ( |outcome| ActionCompletion {
12141227 outcome,
12151228 execution_time : start. elapsed ( ) ,
12161229 environment : ModuleEnvironment :: Isolate ,
12171230 memory_in_mb,
1218- context,
1231+ context : context . clone ( ) ,
12191232 unix_timestamp,
1220- caller,
1233+ caller : caller . clone ( ) ,
12211234 log_lines,
12221235 } )
12231236 } ,
@@ -1309,33 +1322,63 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
13091322 } ,
13101323 )
13111324 . await ;
1312- let node_outcome = node_outcome_result?;
1313-
1314- let outcome = ActionOutcome {
1315- udf_path : name. clone ( ) ,
1325+ timer. finish ( ) ;
1326+ node_outcome_result. map ( |node_outcome| {
1327+ let outcome = ActionOutcome {
1328+ udf_path : name. clone ( ) ,
1329+ arguments : arguments. clone ( ) ,
1330+ identity : tx. inert_identity ( ) ,
1331+ unix_timestamp,
1332+ result : node_outcome. result . map ( JsonPackedValue :: pack) ,
1333+ syscall_trace : node_outcome. syscall_trace ,
1334+ udf_server_version,
1335+ } ;
1336+ ActionCompletion {
1337+ outcome,
1338+ execution_time : start. elapsed ( ) ,
1339+ environment : ModuleEnvironment :: Node ,
1340+ memory_in_mb : node_outcome. memory_used_in_mb ,
1341+ context : context. clone ( ) ,
1342+ unix_timestamp,
1343+ caller : caller. clone ( ) ,
1344+ log_lines,
1345+ }
1346+ } )
1347+ } ,
1348+ ModuleEnvironment :: Invalid => {
1349+ Err ( anyhow:: anyhow!( "Attempting to run an invalid function" ) )
1350+ } ,
1351+ } ;
1352+ match completion_result {
1353+ Ok ( c) => Ok ( c) ,
1354+ Err ( e) if e. is_deterministic_user_error ( ) => {
1355+ let outcome = ActionOutcome :: from_error (
1356+ JsError :: from_error ( e) ,
1357+ name,
13161358 arguments,
1317- identity : tx. inert_identity ( ) ,
1318- unix_timestamp,
1319- result : node_outcome. result . map ( JsonPackedValue :: pack) ,
1320- syscall_trace : node_outcome. syscall_trace ,
1359+ inert_identity,
1360+ self . runtime . clone ( ) ,
13211361 udf_server_version,
1322- } ;
1323- timer. finish ( ) ;
1324- let memory_in_mb = node_outcome. memory_used_in_mb ;
1362+ ) ;
13251363 Ok ( ActionCompletion {
13261364 outcome,
13271365 execution_time : start. elapsed ( ) ,
1328- environment : ModuleEnvironment :: Node ,
1329- memory_in_mb,
1366+ environment : module_version. environment ,
1367+ memory_in_mb : match module_version. environment {
1368+ ModuleEnvironment :: Isolate => ( * ISOLATE_MAX_USER_HEAP_SIZE / ( 1 << 20 ) )
1369+ . try_into ( )
1370+ . unwrap ( ) ,
1371+ // This isn't correct but we don't have a value to use here.
1372+ ModuleEnvironment :: Node => 0 ,
1373+ ModuleEnvironment :: Invalid => 0 ,
1374+ } ,
13301375 context,
13311376 unix_timestamp,
13321377 caller,
1333- log_lines,
1378+ log_lines : vec ! [ ] . into ( ) ,
13341379 } )
13351380 } ,
1336- ModuleEnvironment :: Invalid => {
1337- anyhow:: bail!( "Attempting to run an invalid function" )
1338- } ,
1381+ Err ( e) => Err ( e) ,
13391382 }
13401383 }
13411384
@@ -1379,7 +1422,9 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
13791422 let unix_timestamp = self . runtime . unix_timestamp ( ) ;
13801423 let context = ExecutionContext :: new ( request_id, & caller) ;
13811424
1382- let route = http_request. head . route_for_failure ( ) ?;
1425+ let route = http_request. head . route_for_failure ( ) ;
1426+ let http_request_head = http_request. head . clone ( ) ;
1427+ let inert_identity = InertIdentity :: from ( identity. clone ( ) ) ;
13831428 let ( log_line_sender, log_line_receiver) = mpsc:: unbounded ( ) ;
13841429 let outcome_future = self
13851430 . http_actions
@@ -1407,16 +1452,53 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
14071452 )
14081453 } )
14091454 . await ;
1410- let outcome = outcome_result?;
1411- self . function_log . log_http_action (
1412- outcome. clone ( ) ,
1413- log_lines,
1414- start. elapsed ( ) ,
1415- caller,
1416- usage_tracker,
1417- context,
1418- ) ;
1419- Ok ( outcome. result )
1455+ match outcome_result {
1456+ Ok ( outcome) => {
1457+ let result = outcome. result . clone ( ) ;
1458+ self . function_log . log_http_action (
1459+ outcome,
1460+ log_lines,
1461+ start. elapsed ( ) ,
1462+ caller,
1463+ usage_tracker,
1464+ context,
1465+ ) ;
1466+ Ok ( result)
1467+ } ,
1468+ Err ( e) if e. is_deterministic_user_error ( ) => {
1469+ let result = Err ( JsError :: from_error ( e) ) ;
1470+ let outcome = HttpActionOutcome :: new (
1471+ None ,
1472+ http_request_head,
1473+ inert_identity,
1474+ unix_timestamp,
1475+ result. clone ( ) ,
1476+ None ,
1477+ None ,
1478+ ) ;
1479+ self . function_log . log_http_action (
1480+ outcome. clone ( ) ,
1481+ log_lines,
1482+ start. elapsed ( ) ,
1483+ caller,
1484+ usage_tracker,
1485+ context,
1486+ ) ;
1487+ Ok ( result)
1488+ } ,
1489+ Err ( e) => {
1490+ self . function_log . log_http_action_system_error (
1491+ & e,
1492+ http_request_head,
1493+ inert_identity,
1494+ start,
1495+ caller,
1496+ log_lines,
1497+ context,
1498+ ) ;
1499+ Err ( e)
1500+ } ,
1501+ }
14201502 }
14211503
14221504 #[ minitrace:: trace]
@@ -1750,39 +1832,6 @@ impl<RT: Runtime> ApplicationFunctionRunner<RT> {
17501832 Ok ( Some ( result) )
17511833 }
17521834
1753- pub async fn log_udf_system_error (
1754- & self ,
1755- udf_path : CanonicalizedUdfPath ,
1756- arguments : ConvexArray ,
1757- identity : InertIdentity ,
1758- start : RT :: Instant ,
1759- caller : FunctionCaller ,
1760- e : & anyhow:: Error ,
1761- context : ExecutionContext ,
1762- ) -> anyhow:: Result < ( ) > {
1763- // TODO: We currently synthesize a `UdfOutcome` for
1764- // an internal system error. If we decide we want to keep internal system errors
1765- // in the UDF execution log, we may want to plumb through stuff like log lines.
1766- let outcome = UdfOutcome :: from_error (
1767- JsError :: from_error_ref ( e) ,
1768- udf_path,
1769- arguments,
1770- identity,
1771- self . runtime . clone ( ) ,
1772- None ,
1773- ) ;
1774- self . function_log . log_mutation (
1775- outcome,
1776- BTreeMap :: new ( ) ,
1777- start. elapsed ( ) ,
1778- caller,
1779- true ,
1780- FunctionUsageTracker :: new ( ) ,
1781- context,
1782- ) ;
1783- Ok ( ( ) )
1784- }
1785-
17861835 #[ minitrace:: trace]
17871836 async fn write_mutation_status (
17881837 & self ,
0 commit comments