<commit_before>//
//  ErrorHandler.swift
//  FireAlarm
//
//  Created by <NAME> on 11/22/16.
//  Copyright © 2016 NobodyNada. All rights reserved.
//

import Foundation
import Dispatch

public var errorRoom: ChatRoom?

public func errorAsNSError(_ error: Error) -> NSError? {
	#if os(Linux)
		//this is the only way I could find to check if an arbitrary Error is an NSError that doesn't crash on Linux
		//it produces a warning "'is' test is always true"
		return error is AnyObject ? unsafeBitCast(error, to: NSError.self) : nil
	#else
		return type(of: error) == NSError.self ? error as NSError : nil
	#endif
}

public func formatNSError(_ e: NSError) -> String {
	return "\(e.domain) code \(e.code) \(e.userInfo)"
}

///The maximum amount of errors that can occur in a 30-second period.
public var maxErrors = 2

///What to do after too many errors.  Defaults to calling `abort`.
public var afterTooManyErrors: () -> () = { abort() }

///How many errors have occured within the last 30 seconds.
public var errorsInLast30Seconds = 0

///A string that will be appended to the error message so that the bot's author can be pinged by errors..
public var ping = " (cc @NobodyNada)"

///Logs an error.
public func handleError(_ error: Error, _ context: String? = nil) {
	let contextStr: String
	let errorType: String
	let errorDetails: String
	
	#if os(Linux)
		if let e = errorAsNSError(error) {
			errorType = "NSError"
			errorDetails = formatNSError(e)
		} else {
			errorType = String(reflecting: type(of: error))
			errorDetails = String(describing: error)
		}
	#else
		errorType = String(reflecting: type(of: error))
		errorDetails = String(describing: error)
	#endif
	
	if context != nil {
		contextStr = " \(context!)"
	}
	else {
		contextStr = ""
	}
	
	let message1 = "    An error (\(errorType)) occured\(contextStr)\(ping):"
	
	if let room = errorRoom {
		room.postMessage(message1 + "\n    " + errorDetails.replacingOccurrences(of: "\n", with: "\n    "))
	}
	else {
		print("\(message1)\n\(errorDetails)")
		exit(1)
	}
	
	errorsInLast30Seconds += 1
	if errorsInLast30Seconds > maxErrors {
		afterTooManyErrors()
	}
	
	DispatchQueue.global(qos: .background).async {
		sleep(30)
		errorsInLast30Seconds -= 1
	}
}
<commit_msg>pingonerror command updates<commit_after>//
//  ErrorHandler.swift
//  FireAlarm
//
//  Created by <NAME> on 11/22/16.
//  Copyright © 2016 NobodyNada. All rights reserved.
//

import Foundation
import Dispatch

public var errorRoom: ChatRoom?

public func errorAsNSError(_ error: Error) -> NSError? {
	#if os(Linux)
		//this is the only way I could find to check if an arbitrary Error is an NSError that doesn't crash on Linux
		//it produces a warning "'is' test is always true"
		return error is AnyObject ? unsafeBitCast(error, to: NSError.self) : nil
	#else
		return type(of: error) == NSError.self ? error as NSError : nil
	#endif
}

public func formatNSError(_ e: NSError) -> String {
	return "\(e.domain) code \(e.code) \(e.userInfo)"
}

///The maximum amount of errors that can occur in a 30-second period.
public var maxErrors = 2

///What to do after too many errors.  Defaults to calling `abort`.
public var afterTooManyErrors: () -> () = { abort() }

///How many errors have occured within the last 30 seconds.
public var errorsInLast30Seconds = 0

///A string that will be appended to the error message so that the bot's author can be pinged by errors..
public var ping = " (cc @<enter owner name here>)"

///A bool variable which will control the usage of the ping ^ variable.
public var pingonerror = true

///Logs an error.
public func handleError(_ error: Error, _ context: String? = nil) {
	let contextStr: String
	let errorType: String
	let errorDetails: String
	
	#if os(Linux)
		if let e = errorAsNSError(error) {
			errorType = "NSError"
			errorDetails = formatNSError(e)
		} else {
			errorType = String(reflecting: type(of: error))
			errorDetails = String(describing: error)
		}
	#else
		errorType = String(reflecting: type(of: error))
		errorDetails = String(describing: error)
	#endif
	
	if context != nil {
		contextStr = " \(context!)"
	}
	else {
		contextStr = ""
	}
    
    let message1: String
    
    if (pingonerror == true) {
        message1 = "    An error (\(errorType)) occured\(contextStr)\(ping):"
    } else {
        message1 = "    An error (\(errorType)) occured\(contextStr):"
    }
	
	if let room = errorRoom {
		room.postMessage(message1 + "\n    " + errorDetails.replacingOccurrences(of: "\n", with: "\n    "))
	}
	else {
		print("\(message1)\n\(errorDetails)")
		exit(1)
	}
	
	errorsInLast30Seconds += 1
	if errorsInLast30Seconds > maxErrors {
		afterTooManyErrors()
	}
	
	DispatchQueue.global(qos: .background).async {
		sleep(30)
		errorsInLast30Seconds -= 1
	}
}

{'fraction_non_alphanumeric': 0.12055543867031349, 'fraction_numerical': 0.013885966757837155, 'mean_word_length': 3.4141132776230267, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2349962', 'n_tokens_mistral': 1714, 'n_tokens_neox': 1542, 'n_words': 522}