egametang/ET · error · Exception
add cancel token is null
Error message
add cancel token is null
What it means
Thrown by ETCancellationTokenHelper.AddCancel(this ETTask, ETCancellationToken) when addCancelToken is null. The extension chains a new cancellation source onto the task's context, so a null token cannot be wired up and is rejected up front with a plain Exception. This is the ET coroutine framework's precondition guard.
Source
Thrown at Packages/cn.etetet.core/Scripts/Core/Share/ETCancellationToken/ETCancellationTokenHelper.cs:44
}
// 这里用了Fiber.Instance是因为我知道有什么后果, 你们千万不能乱用这个Fiber.Instance
await Fiber.Instance.Root.TimerComponent.WaitAsync(afterTimeCancel);
if (self.IsCancel())
{
return;
}
self.Cancel();
}
/// <summary>
/// 增加一个canceltoken,可以用新增的canceltoken取消协程,当然也可以用老的取消
/// </summary>
public static async ETTask AddCancel(this ETTask task, ETCancellationToken addCancelToken)
{
if (addCancelToken == null)
{
throw new Exception("add cancel token is null");
}
ETCancellationToken cancelToken = await ETTask.GetContextAsync<ETCancellationToken>();
cancelToken?.Add(addCancelToken.Cancel);
await task.NewContext(addCancelToken);
}
/// <summary>
/// 增加一个canceltoken,可以用新增的canceltoken取消协程,当然也可以用老的取消
/// </summary>
public static async ETTask<T> AddCancel<T>(this ETTask<T> task, ETCancellationToken addCancelToken)
{
if (addCancelToken == null)
{
throw new Exception("add cancel token is null");
}
View on GitHub (pinned to 5cab01f7a8)
Solutions
- Construct the token before calling: var token = new ETCancellationToken(); await task.AddCancel(token);
- For no-cancel cases, simply await the task directly instead of calling AddCancel(null).
- Prefer the TimeoutAsync(this ETTask, long afterTimeCancel) overload which creates the token internally.
Example fix
// before await task.AddCancel(null); // throws // after await task.AddCancel(new ETCancellationToken());
Defensive patterns
Strategy: validation
Validate before calling
// Construct the token before calling AddCancel. if (addCancelToken == null) addCancelToken = new ETCancellationToken(); await task.AddCancel(addCancelToken);
Type guard
static bool IsValidToken(ETCancellationToken t) => t != null && !t.IsDispose();
Prevention
- Prefer TimeoutAsync(task, afterTimeCancel) which creates the token for you.
- Initialize token fields at construction, never pass null.
- Skip AddCancel entirely when no cancellation is needed.
When it happens
Trigger: Calling task.AddCancel(null); passing a token field that was never assigned; reusing a token after it was disposed and set to null; calling the overload that creates a token implicitly but forwarding null by mistake.
Common situations: Forgetting to construct ETCancellationToken before calling AddCancel/TimeoutAsync; refactors that removed token creation; conditional code paths that pass null when no timeout is desired (should skip the call instead).
Related errors
- ETTask does not allow call GetResult directly when task not
- TaskT_TransitionToFinal_AlreadyCompleted
- btenv not found key: {key} {typeof(T).FullName}
- 不能把{value.GetType()}转换为{typeof (T)}
- condition root child count error: {node.Children.Count}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/438df7b9031db8c7.
Report an issue: GitHub.