Skip to content

Commit 816a029

Browse files
fix: Adding a try/catch around the function call for an RPC (#1329) (#1343)
Co-authored-by: Matt Walsh <[email protected]>
1 parent fbd3d06 commit 816a029

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,11 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
11271127
nhandler.Parameters.Add(new ParameterDefinition("rpcParams", ParameterAttributes.None, m_RpcParams_TypeRef));
11281128

11291129
var processor = nhandler.Body.GetILProcessor();
1130+
1131+
// begin Try/Catch
1132+
var tryStart = processor.Create(OpCodes.Nop);
1133+
processor.Append(tryStart);
1134+
11301135
var isServerRpc = rpcAttribute.AttributeType.FullName == CodeGenHelpers.ServerRpcAttribute_FullName;
11311136
var requireOwnership = true; // default value MUST be = `ServerRpcAttribute.RequireOwnership`
11321137
foreach (var attrField in rpcAttribute.Fields)
@@ -1303,7 +1308,51 @@ private MethodDefinition GenerateStaticHandler(MethodDefinition methodDefinition
13031308
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
13041309
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
13051310

1311+
//try ends/catch begins
1312+
var catchEnds = processor.Create(OpCodes.Nop);
1313+
processor.Emit(OpCodes.Leave, catchEnds);
1314+
1315+
// Load the Exception onto the stack
1316+
var catchStarts = processor.Create(OpCodes.Stloc_0);
1317+
processor.Append(catchStarts);
1318+
1319+
// pull in the Exception Module
1320+
var exception = m_MainModule.ImportReference(typeof(Exception));
1321+
1322+
// Get Exception.ToString()
1323+
var exp = m_MainModule.ImportReference(typeof(Exception).GetMethod("ToString", new Type[] { }));
1324+
1325+
// Get String.Format (This is equivelent to an interpolated string)
1326+
var stringFormat = m_MainModule.ImportReference(typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) }));
1327+
1328+
// Load string for the error log that will be shown
1329+
processor.Emit(OpCodes.Ldstr, $"Unhandled RPC Exception:\n {{0}}");
1330+
processor.Emit(OpCodes.Ldloc_0);
1331+
processor.Emit(OpCodes.Callvirt, exp);
1332+
processor.Emit(OpCodes.Call, stringFormat);
1333+
1334+
// Call Debug.LogError
1335+
processor.Emit(OpCodes.Call, m_Debug_LogError_MethodRef);
1336+
1337+
// reset NetworkBehaviour.__rpc_exec_stage = __RpcExecStage.None;
1338+
processor.Emit(OpCodes.Ldarg_0);
1339+
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
1340+
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
1341+
1342+
// catch ends
1343+
processor.Append(catchEnds);
1344+
1345+
processor.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
1346+
{
1347+
CatchType = exception,
1348+
TryStart = tryStart,
1349+
TryEnd = catchStarts,
1350+
HandlerStart = catchStarts,
1351+
HandlerEnd = catchEnds
1352+
});
1353+
13061354
processor.Emit(OpCodes.Ret);
1355+
13071356
return nhandler;
13081357
}
13091358
}

0 commit comments

Comments
 (0)