improves error reporting for discord bot
This commit is contained in:
parent
e29ffe4f9c
commit
9e842207ab
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
public RewardUsersCommand[] Rewards { get; set; } = Array.Empty<RewardUsersCommand>();
|
||||
public ChainEventMessage[] EventsOverview { get; set; } = Array.Empty<ChainEventMessage>();
|
||||
public string[] Errors { get; set; } = Array.Empty<string>();
|
||||
|
||||
public bool HasAny()
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex);
|
||||
void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex);
|
||||
void OnSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex);
|
||||
|
||||
void OnError(string msg);
|
||||
}
|
||||
|
||||
public class RequestEvent
|
||||
|
@ -67,7 +69,11 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
private void Apply(ChainEvents events)
|
||||
{
|
||||
if (events.BlockInterval.TimeRange.From < TotalSpan.From)
|
||||
throw new Exception("Attempt to update ChainState with set of events from before its current record.");
|
||||
{
|
||||
var msg = "Attempt to update ChainState with set of events from before its current record.";
|
||||
handler.OnError(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
log.Log($"ChainState updating: {events.BlockInterval}");
|
||||
|
||||
|
@ -110,7 +116,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(RequestFulfilledEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.UpdateState(@event.Block.BlockNumber, RequestState.Started);
|
||||
handler.OnRequestFulfilled(new RequestEvent(@event.Block, r));
|
||||
|
@ -118,7 +124,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(RequestCancelledEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.UpdateState(@event.Block.BlockNumber, RequestState.Cancelled);
|
||||
handler.OnRequestCancelled(new RequestEvent(@event.Block, r));
|
||||
|
@ -126,7 +132,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(RequestFailedEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.UpdateState(@event.Block.BlockNumber, RequestState.Failed);
|
||||
handler.OnRequestFailed(new RequestEvent(@event.Block, r));
|
||||
|
@ -134,7 +140,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(SlotFilledEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.Hosts.Add(@event.Host, (int)@event.SlotIndex);
|
||||
r.Log($"[{@event.Block.BlockNumber}] SlotFilled (host:'{@event.Host}', slotIndex:{@event.SlotIndex})");
|
||||
|
@ -143,7 +149,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(SlotFreedEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.Hosts.RemoveHost((int)@event.SlotIndex);
|
||||
r.Log($"[{@event.Block.BlockNumber}] SlotFreed (slotIndex:{@event.SlotIndex})");
|
||||
|
@ -152,7 +158,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
|
||||
private void ApplyEvent(SlotReservationsFullEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) return;
|
||||
r.Log($"[{@event.Block.BlockNumber}] SlotReservationsFull (slotIndex:{@event.SlotIndex})");
|
||||
handler.OnSlotReservationsFull(new RequestEvent(@event.Block, r), @event.SlotIndex);
|
||||
|
@ -171,10 +177,23 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
}
|
||||
}
|
||||
|
||||
private ChainStateRequest? FindRequest(byte[] requestId)
|
||||
private ChainStateRequest? FindRequest(IHasRequestId request)
|
||||
{
|
||||
var r = requests.SingleOrDefault(r => Equal(r.Request.RequestId, requestId));
|
||||
if (r == null) log.Log("Unable to find request by ID!");
|
||||
var r = requests.SingleOrDefault(r => Equal(r.Request.RequestId, request.RequestId));
|
||||
if (r == null)
|
||||
{
|
||||
var blockNumber = "unknown";
|
||||
if (request is IHasBlock blk)
|
||||
{
|
||||
blockNumber = blk.Block.BlockNumber.ToString();
|
||||
}
|
||||
|
||||
var msg = $"Received event of type '{request.GetType()}' in block '{blockNumber}' for request by Id: '{request.RequestId}'. " +
|
||||
$"Failed to find request. Request creation event not seen! (Tracker start time: {TotalSpan.From})";
|
||||
|
||||
log.Error(msg);
|
||||
handler.OnError(msg);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
using GethPlugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
|
@ -56,5 +51,10 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
{
|
||||
foreach (var handler in Handlers) handler.OnSlotReservationsFull(requestEvent, slotIndex);
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnError(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,5 +36,9 @@ namespace CodexContractsPlugin.ChainMonitor
|
|||
public void OnSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,12 @@ namespace CodexContractsPlugin.Marketplace
|
|||
BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class Request : RequestBase, IHasBlock
|
||||
public interface IHasRequestId
|
||||
{
|
||||
byte[] RequestId { get; set; }
|
||||
}
|
||||
|
||||
public partial class Request : RequestBase, IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
|
@ -28,38 +33,38 @@ namespace CodexContractsPlugin.Marketplace
|
|||
}
|
||||
}
|
||||
|
||||
public partial class RequestFulfilledEventDTO : IHasBlock
|
||||
public partial class RequestFulfilledEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestCancelledEventDTO : IHasBlock
|
||||
public partial class RequestCancelledEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestFailedEventDTO : IHasBlock
|
||||
public partial class RequestFailedEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO : IHasBlock
|
||||
public partial class SlotFilledEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
public EthAddress Host { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFreedEventDTO : IHasBlock
|
||||
public partial class SlotFreedEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlock
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
|
|
|
@ -17,8 +17,10 @@ namespace BiblioTech.Rewards
|
|||
this.eventsChannel = eventsChannel;
|
||||
}
|
||||
|
||||
public async Task ProcessChainEvents(ChainEventMessage[] eventsOverview)
|
||||
public async Task ProcessChainEvents(ChainEventMessage[] eventsOverview, string[] errors)
|
||||
{
|
||||
await SendErrorsToAdminChannel(errors);
|
||||
|
||||
if (eventsChannel == null || eventsOverview == null || !eventsOverview.Any()) return;
|
||||
try
|
||||
{
|
||||
|
@ -34,6 +36,22 @@ namespace BiblioTech.Rewards
|
|||
}
|
||||
}
|
||||
|
||||
private async Task SendErrorsToAdminChannel(string[] errors)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var error in errors)
|
||||
{
|
||||
await Program.AdminChecker.SendInAdminChannel(error);
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.Error("Failed to send error messages to admin channel. " + exc);
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendChainEventsInOrder(ChainEventMessage[] eventsOverview, SocketTextChannel eventsChannel, UserData[] users)
|
||||
{
|
||||
eventsOverview = eventsOverview.OrderBy(e => e.BlockNumber).ToArray();
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace BiblioTech.Rewards
|
|||
await ProcessRewards(rewards);
|
||||
}
|
||||
|
||||
await eventsSender.ProcessChainEvents(rewards.EventsOverview);
|
||||
await eventsSender.ProcessChainEvents(rewards.EventsOverview, rewards.Errors);
|
||||
}
|
||||
|
||||
private async Task ProcessRewards(GiveRewardsCommand rewards)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using CodexContractsPlugin;
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using Nethereum.Model;
|
||||
using TestNetRewarder;
|
||||
using Utils;
|
||||
|
||||
|
@ -40,7 +39,7 @@ namespace MarketInsights
|
|||
|
||||
private MarketTimeSegment BuildContribution(TimeRange timeRange)
|
||||
{
|
||||
var builder = new ContributionBuilder(timeRange);
|
||||
var builder = new ContributionBuilder(appState.Log, timeRange);
|
||||
mux.Handlers.Add(builder);
|
||||
chainState.Update(timeRange.To);
|
||||
mux.Handlers.Remove(builder);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using CodexContractsPlugin.ChainMonitor;
|
||||
using GethPlugin;
|
||||
using Logging;
|
||||
using System.Numerics;
|
||||
using Utils;
|
||||
|
||||
|
@ -8,14 +9,16 @@ namespace MarketInsights
|
|||
public class ContributionBuilder : IChainStateChangeHandler
|
||||
{
|
||||
private readonly MarketTimeSegment segment = new MarketTimeSegment();
|
||||
private readonly ILog log;
|
||||
|
||||
public ContributionBuilder(TimeRange timeRange)
|
||||
public ContributionBuilder(ILog log, TimeRange timeRange)
|
||||
{
|
||||
segment = new MarketTimeSegment
|
||||
{
|
||||
FromUtc = timeRange.From,
|
||||
ToUtc = timeRange.To
|
||||
};
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
|
@ -55,6 +58,11 @@ namespace MarketInsights
|
|||
{
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
log.Error(msg);
|
||||
}
|
||||
|
||||
public MarketTimeSegment GetSegment()
|
||||
{
|
||||
return segment;
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace TestNetRewarder
|
|||
{
|
||||
private static readonly string nl = Environment.NewLine;
|
||||
private readonly List<ChainEventMessage> events = new List<ChainEventMessage>();
|
||||
private readonly List<string> errors = new List<string>();
|
||||
private readonly EmojiMaps emojiMaps = new EmojiMaps();
|
||||
|
||||
public ChainEventMessage[] GetEvents()
|
||||
|
@ -21,9 +22,11 @@ namespace TestNetRewarder
|
|||
return result;
|
||||
}
|
||||
|
||||
public void AddError(string error)
|
||||
public string[] GetErrors()
|
||||
{
|
||||
AddBlock(1, "📢 **Error**", error);
|
||||
var result = errors.ToArray();
|
||||
errors.Clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
|
@ -83,6 +86,11 @@ namespace TestNetRewarder
|
|||
$"Slot Index: {slotIndex}"
|
||||
);
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
errors.Add(msg);
|
||||
}
|
||||
|
||||
private void AddRequestBlock(RequestEvent requestEvent, string eventName, params string[] content)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace TestNetRewarder
|
|||
{
|
||||
var msg = "Exception processing time segment: " + ex;
|
||||
log.Error(msg);
|
||||
eventsFormatter.AddError(msg);
|
||||
eventsFormatter.OnError(msg);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,9 @@ namespace TestNetRewarder
|
|||
var numberOfChainEvents = chainState.Update(timeRange.To);
|
||||
|
||||
var events = eventsFormatter.GetEvents();
|
||||
var errors = eventsFormatter.GetErrors();
|
||||
|
||||
var request = builder.Build(events);
|
||||
var request = builder.Build(events, errors);
|
||||
if (request.HasAny())
|
||||
{
|
||||
await client.SendRewards(request);
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace TestNetRewarder
|
|||
}
|
||||
}
|
||||
|
||||
public GiveRewardsCommand Build(ChainEventMessage[] lines)
|
||||
public GiveRewardsCommand Build(ChainEventMessage[] lines, string[] errors)
|
||||
{
|
||||
var result = new GiveRewardsCommand
|
||||
{
|
||||
|
@ -28,7 +28,8 @@ namespace TestNetRewarder
|
|||
RewardId = p.Key,
|
||||
UserAddresses = p.Value.Select(v => v.Address).ToArray()
|
||||
}).ToArray(),
|
||||
EventsOverview = lines
|
||||
EventsOverview = lines,
|
||||
Errors = errors
|
||||
};
|
||||
|
||||
rewards.Clear();
|
||||
|
|
|
@ -76,6 +76,10 @@ namespace TestNetRewarder
|
|||
{
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
}
|
||||
|
||||
private void GiveReward(RewardConfig reward, EthAddress receiver)
|
||||
{
|
||||
giver.Give(reward, receiver);
|
||||
|
|
Loading…
Reference in New Issue