packages feed

bugsnag-types (empty) → 1.0.0.0

raw patch · 29 files changed

+2003/−0 lines, 29 filesdep +aesondep +basedep +bugsnag-types

Dependencies added: aeson, base, bugsnag-types, hspec, text

Files

+ CHANGELOG.md view
+ README.md view
+ bugsnag-types.cabal view
@@ -0,0 +1,102 @@+cabal-version:   1.18+name:            bugsnag-types+version:         1.0.0.0+license:         MIT+maintainer:      pbrisbin@gmail.com+author:          Patrick Brisbin+homepage:        https://codeberg.org/pbrisbin/bugsnag-haskell#readme+synopsis:        Types for the Bugsnag error reporter for Haskell+description:     Please see README.md+category:        Web+build-type:      Simple+extra-doc-files:+    CHANGELOG.md+    README.md++flag examples+    description: Build the examples+    default:     False++library+    exposed-modules:+        Data.Bugsnag.Types.Application+        Data.Bugsnag.Types.BinaryArch+        Data.Bugsnag.Types.Breadcrumb+        Data.Bugsnag.Types.BreadcrumbType+        Data.Bugsnag.Types.DependentNotifier+        Data.Bugsnag.Types.Device+        Data.Bugsnag.Types.ErrorType+        Data.Bugsnag.Types.Event+        Data.Bugsnag.Types.Exception+        Data.Bugsnag.Types.FeatureFlag+        Data.Bugsnag.Types.Notifier+        Data.Bugsnag.Types.Payload+        Data.Bugsnag.Types.Prelude+        Data.Bugsnag.Types.Request+        Data.Bugsnag.Types.RuntimeVersion+        Data.Bugsnag.Types.Session+        Data.Bugsnag.Types.SessionEvent+        Data.Bugsnag.Types.Severity+        Data.Bugsnag.Types.SeverityReason+        Data.Bugsnag.Types.SeverityReasonAttributes+        Data.Bugsnag.Types.SeverityReasonType+        Data.Bugsnag.Types.Stackframe+        Data.Bugsnag.Types.Thread+        Data.Bugsnag.Types.User++    hs-source-dirs:     src+    other-modules:      Paths_bugsnag_types+    default-language:   GHC2021+    default-extensions:+        DeriveAnyClass DerivingStrategies DuplicateRecordFields LambdaCase+        NoFieldSelectors NoImplicitPrelude OverloadedRecordDot+        OverloadedStrings++    ghc-options:+        -fwrite-ide-info -Weverything -Wno-all-missed-specialisations+        -Wno-missed-specialisations -Wno-missing-exported-signatures+        -Wno-missing-import-lists -Wno-missing-kind-signatures+        -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+        -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+        -Wno-safe -Wno-unsafe++    build-depends:+        aeson >=2.1.2.1,+        base >=4.17.2.1 && <5,+        text >=2.0.2++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++test-suite spec+    type:               exitcode-stdio-1.0+    main-is:            Spec.hs+    hs-source-dirs:     test+    other-modules:+        Data.Bugsnag.Types.PayloadSpec+        Paths_bugsnag_types++    default-language:   GHC2021+    default-extensions:+        DeriveAnyClass DerivingStrategies DuplicateRecordFields LambdaCase+        NoFieldSelectors NoImplicitPrelude OverloadedRecordDot+        OverloadedStrings++    ghc-options:+        -fwrite-ide-info -Weverything -Wno-all-missed-specialisations+        -Wno-missed-specialisations -Wno-missing-exported-signatures+        -Wno-missing-import-lists -Wno-missing-kind-signatures+        -Wno-missing-local-signatures -Wno-missing-safe-haskell-mode+        -Wno-monomorphism-restriction -Wno-prepositive-qualified-module+        -Wno-safe -Wno-unsafe -threaded -rtsopts -with-rtsopts=-N++    build-depends:+        aeson >=2.1.2.1,+        base >=4.17.2.1 && <5,+        bugsnag-types,+        hspec >=2.10.10++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures
+ src/Data/Bugsnag/Types/Application.hs view
@@ -0,0 +1,105 @@+module Data.Bugsnag.Types.Application+  ( Application (..)+  , exampleApplication+  , defaultApplication+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.BinaryArch++-- | Information about the app where the error occurred. These fields are+-- optional but highly recommended. To display custom app data alongside+-- these standard fields on the dashboard, the custom data should be+-- included in the @metaData@ object in an @app@ object.+data Application = Application+  { id :: Maybe Text+  -- ^ A unique ID for the application.+  , version :: Maybe Text+  -- ^ The version number of the application which generated the error.+  , versionCode :: Maybe Int+  -- ^ The+  -- <https://developer.android.com/studio/publish/versioning.html version code>+  -- of the application (Android only)+  , bundleVersion :: Maybe Text+  -- ^ The+  -- <https://developer.apple.com/library/content/technotes/tn2420/_index.html bundle version\/build number>+  -- of the application (iOS\/macOS\/tvOS only)+  , codeBundleId :: Maybe Text+  -- ^ A unique identifier to identify a code bundle release when using tools+  -- like CodePush (mobile only).+  , buildUUID :: Maybe Text+  -- ^ A build ID that is required to identify a specific build when the+  -- version and version code are the same.+  , releaseStage :: Maybe Text+  -- ^ The release stage that this error occurred in, for example+  -- \"development\", \"staging\" or \"production\".+  , type_ :: Maybe Text+  -- ^ A specialized type of the application, such as the worker queue or web+  -- framework used, like \"rails\", \"mailman\", or \"celery\".+  , dsymUUIDs :: Maybe [Text]+  -- ^ The UUIDs of the <http://lldb.llvm.org/symbols.html debug symbols file>+  -- corresponding to this application, if any.+  , duration :: Maybe Int+  -- ^ How long the app has been running for in milliseconds.+  , durationInForeground :: Maybe Int+  -- ^ How long the app has been in the foreground of the device in+  -- milliseconds.+  , inForeground :: Maybe Bool+  -- ^ Whether or not the app was in the foreground when the error occurred.+  , isLaunching :: Maybe Bool+  -- ^ Whether or not the app was still launching when the error occurred.+  , binaryArch :: Maybe BinaryArch+  -- ^ The architecture of the running binary.+  , runningOnRosetta :: Maybe Bool+  -- ^ Whether the application is running on the Rosetta emulator for Mac.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Application where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Application where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultApplication :: Application+defaultApplication =+  Application+    { id = Nothing+    , version = Nothing+    , versionCode = Nothing+    , bundleVersion = Nothing+    , codeBundleId = Nothing+    , buildUUID = Nothing+    , releaseStage = Nothing+    , type_ = Nothing+    , dsymUUIDs = Nothing+    , duration = Nothing+    , durationInForeground = Nothing+    , inForeground = Nothing+    , isLaunching = Nothing+    , binaryArch = Nothing+    , runningOnRosetta = Nothing+    }++exampleApplication :: Application+exampleApplication =+  Application+    { id = Just "com.bugsnag.android.example.debug"+    , version = Just "1.1.3"+    , versionCode = Just 12+    , bundleVersion = Just "1.0.2"+    , codeBundleId = Just "1.0-1234"+    , buildUUID = Just "BE5BA3D0-971C-4418-9ECF-E2D1ABCB66BE"+    , releaseStage = Just "staging"+    , type_ = Just "rails"+    , dsymUUIDs = Just ["e6173678256785afd940392abee"]+    , duration = Just 1275+    , durationInForeground = Just 983+    , inForeground = Just True+    , isLaunching = Just True+    , binaryArch = Just exampleBinaryArch+    , runningOnRosetta = Just True+    }
+ src/Data/Bugsnag/Types/BinaryArch.hs view
@@ -0,0 +1,33 @@+module Data.Bugsnag.Types.BinaryArch+  ( BinaryArch (..)+  , exampleBinaryArch+  )+where++import Data.Bugsnag.Types.Prelude++-- | The architecture of the running binary.+data BinaryArch+  = X86+  | X86_64+  | Arm32+  | Arm64+  | Arm64e+  | Armv6+  | Armv7+  | Armv7f+  | Armv7k+  | Armv7s+  | Armv8+  | Amd64+  deriving stock (Bounded, Enum, Eq, Generic, Show)++instance FromJSON BinaryArch where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON BinaryArch where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++exampleBinaryArch :: BinaryArch+exampleBinaryArch = X86
+ src/Data/Bugsnag/Types/Breadcrumb.hs view
@@ -0,0 +1,77 @@+module Data.Bugsnag.Types.Breadcrumb+  ( Breadcrumb (..)+  , exampleBreadcrumb+  , defaultBreadcrumb+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.BreadcrumbType++data Breadcrumb = Breadcrumb+  { timestamp :: Text+  -- ^ The time at which the event occurred, in+  -- <https://tools.ietf.org/html/rfc3339#section-5.8 ISO 8601 format>.+  , name :: Text+  -- ^ A short summary describing the event, such as the user action taken or a+  -- new application state.+  , type_ :: BreadcrumbType+  -- ^ A category which describes the breadcrumb, from the list of allowed+  -- values.+  --+  -- -   @navigation@ - Changing screens or content being displayed, with a+  --     defined destination and optionally a previous location.+  --+  -- -   @request@ - Sending and receiving requests and responses.+  --+  -- -   @process@ - Performing an intensive task or query.+  --+  -- -   @log@ - Messages and severity sent to a logging platform.+  --+  -- -   @user@ - Actions performed by the user, like text input, button+  --     presses, or confirming\/cancelling an alert dialog.+  --+  -- -   @state@ - Changing the overall state of an app, such as closing,+  --     pausing, or being moved to the background, as well as device state+  --     changes like memory or battery warnings and network connectivity+  --     changes.+  --+  -- -   @error@ - An error which was reported to BugSnag encountered in the+  --     same session.+  --+  -- -   @manual@ - User-defined, manually added breadcrumbs.+  , metaData :: Maybe (KeyMap Text)+  -- ^ Additional information about the event, as key\/value pairs.+  --+  -- > {+  -- >     "to": "PauseView",+  -- >     "from": "PodBayDoorView"+  -- > }+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Breadcrumb where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Breadcrumb where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultBreadcrumb :: Text -> Text -> BreadcrumbType -> Breadcrumb+defaultBreadcrumb timestamp name type_ =+  Breadcrumb+    { timestamp+    , name+    , type_+    , metaData = Nothing+    }++exampleBreadcrumb :: Breadcrumb+exampleBreadcrumb =+  Breadcrumb+    { timestamp = "2016-07-19T12:17:27-0700"+    , name = "Open menu"+    , type_ = exampleBreadcrumbType+    , metaData = Nothing+    }
+ src/Data/Bugsnag/Types/BreadcrumbType.hs view
@@ -0,0 +1,52 @@+module Data.Bugsnag.Types.BreadcrumbType+  ( BreadcrumbType (..)+  , exampleBreadcrumbType+  )+where++import Data.Bugsnag.Types.Prelude++-- | A category which describes the breadcrumb, from the list of allowed+-- values.+--+-- -   @navigation@ - Changing screens or content being displayed, with a+--     defined destination and optionally a previous location.+--+-- -   @request@ - Sending and receiving requests and responses.+--+-- -   @process@ - Performing an intensive task or query.+--+-- -   @log@ - Messages and severity sent to a logging platform.+--+-- -   @user@ - Actions performed by the user, like text input, button+--     presses, or confirming\/cancelling an alert dialog.+--+-- -   @state@ - Changing the overall state of an app, such as closing,+--     pausing, or being moved to the background, as well as device state+--     changes like memory or battery warnings and network connectivity+--     changes.+--+-- -   @error@ - An error which was reported to BugSnag encountered in the+--     same session.+--+-- -   @manual@ - User-defined, manually added breadcrumbs.+data BreadcrumbType+  = Navigation+  | Request+  | Process+  | Log+  | User+  | State+  | Error+  | Manual+  deriving stock (Bounded, Enum, Eq, Generic, Show)++instance FromJSON BreadcrumbType where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON BreadcrumbType where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++exampleBreadcrumbType :: BreadcrumbType+exampleBreadcrumbType = Navigation
+ src/Data/Bugsnag/Types/DependentNotifier.hs view
@@ -0,0 +1,41 @@+module Data.Bugsnag.Types.DependentNotifier+  ( DependentNotifier (..)+  , exampleDependentNotifier+  , defaultDependentNotifier+  )+where++import Data.Bugsnag.Types.Prelude++data DependentNotifier = DependentNotifier+  { name :: Text+  -- ^ The notifier name.+  , version :: Text+  -- ^ The notifier\'s current version.+  , url :: Text+  -- ^ The URL associated with the notifier.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON DependentNotifier where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON DependentNotifier where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultDependentNotifier :: Text -> Text -> Text -> DependentNotifier+defaultDependentNotifier name version url =+  DependentNotifier+    { name+    , version+    , url+    }++exampleDependentNotifier :: DependentNotifier+exampleDependentNotifier =+  DependentNotifier+    { name = "Bugsnag Android"+    , version = "2.1.10"+    , url = "https://github.com/bugsnag/bugsnag-android"+    }
+ src/Data/Bugsnag/Types/Device.hs view
@@ -0,0 +1,108 @@+module Data.Bugsnag.Types.Device+  ( Device (..)+  , exampleDevice+  , defaultDevice+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.RuntimeVersion++-- | Information about the computer\/device running the app. These fields are+-- optional but highly recommended. To display custom device data alongside+-- these standard fields on the dashboard, the custom data should be+-- included in the @metaData@ object in a @device@ object.+data Device = Device+  { hostname :: Maybe Text+  -- ^ The hostname of the server running your code, if applicable.+  , id :: Maybe Text+  -- ^ A unique identifier for the device.+  , manufacturer :: Maybe Text+  -- ^ The manufacturer of the device.+  , model :: Maybe Text+  -- ^ The model of the device.+  , modelNumber :: Maybe Text+  -- ^ The model number of the device.+  , osName :: Maybe Text+  -- ^ The device\'s operating system name.+  , osVersion :: Maybe Text+  -- ^ The device\'s operating system version.+  , freeMemory :: Maybe Int+  -- ^ The number of bytes unused in the device\'s RAM.+  , totalMemory :: Maybe Int+  -- ^ The number of total bytes in the device\'s RAM.+  , freeDisk :: Maybe Int+  -- ^ The number of unused bytes on the drive running the application.+  , browserName :: Maybe Text+  -- ^ If a web application, the web browser used by the device.+  , browserVersion :: Maybe Text+  -- ^ If a web application, the version of the browser used by the device.+  , jailbroken :: Maybe Bool+  -- ^ Whether or not the device has been modified to give users root access.+  , orientation :: Maybe Text+  -- ^ The orientation of the device at the time of the error.+  , time :: Maybe Text+  -- ^ The time at which the error occurred, in+  -- <https://tools.ietf.org/html/rfc3339#section-5.8 ISO 8601 format>.+  , cpuAbi :: Maybe [Text]+  -- ^ The <https://developer.android.com/ndk/guides/abis ABIs> supported by+  -- the device (Android only).+  , runtimeVersions :: Maybe RuntimeVersion+  , macCatalystiOSVersion :: Maybe Text+  -- ^ The device\'s Mac Catalyst iOS version.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Device where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Device where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultDevice :: Device+defaultDevice =+  Device+    { hostname = Nothing+    , id = Nothing+    , manufacturer = Nothing+    , model = Nothing+    , modelNumber = Nothing+    , osName = Nothing+    , osVersion = Nothing+    , freeMemory = Nothing+    , totalMemory = Nothing+    , freeDisk = Nothing+    , browserName = Nothing+    , browserVersion = Nothing+    , jailbroken = Nothing+    , orientation = Nothing+    , time = Nothing+    , cpuAbi = Nothing+    , runtimeVersions = Nothing+    , macCatalystiOSVersion = Nothing+    }++exampleDevice :: Device+exampleDevice =+  Device+    { hostname = Just "web1.internal"+    , id = Just "fd124e87760c4281aef"+    , manufacturer = Just "LGE"+    , model = Just "Nexus 6P"+    , modelNumber = Just "600"+    , osName = Just "android"+    , osVersion = Just "8.0.1"+    , freeMemory = Just 183879616+    , totalMemory = Just 201326592+    , freeDisk = Just 13478064128+    , browserName = Just "Chrome"+    , browserVersion = Just "61.0.3163.100"+    , jailbroken = Nothing+    , orientation = Just "portrait"+    , time = Just "2018-08-07T10:16:34.564Z"+    , cpuAbi = Just ["x86_64"]+    , runtimeVersions = Just exampleRuntimeVersion+    , macCatalystiOSVersion = Just "14.0"+    }
+ src/Data/Bugsnag/Types/ErrorType.hs view
@@ -0,0 +1,37 @@+module Data.Bugsnag.Types.ErrorType+  ( ErrorType (..)+  , exampleErrorType+  )+where++import Data.Bugsnag.Types.Prelude++-- | This should be set to indicate the type of runtime the thread was+-- running on so that the stacktrace can be parsed correctly.+data ErrorType+  = Android+  | Browserjs+  | C+  | Cocoa+  | Csharp+  | Electronnodejs+  | Electronrendererjs+  | Expojs+  | Go+  | Java+  | Nodejs+  | Php+  | Python+  | Reactnativejs+  | Ruby+  deriving stock (Bounded, Enum, Eq, Generic, Show)++instance FromJSON ErrorType where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON ErrorType where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++exampleErrorType :: ErrorType+exampleErrorType = Android
+ src/Data/Bugsnag/Types/Event.hs view
@@ -0,0 +1,181 @@+module Data.Bugsnag.Types.Event+  ( Event (..)+  , exampleEvent+  , defaultEvent+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.Application+import Data.Bugsnag.Types.Breadcrumb+import Data.Bugsnag.Types.Device+import Data.Bugsnag.Types.Exception+import Data.Bugsnag.Types.FeatureFlag+import Data.Bugsnag.Types.Request+import Data.Bugsnag.Types.Session+import Data.Bugsnag.Types.Severity+import Data.Bugsnag.Types.SeverityReason+import Data.Bugsnag.Types.Thread+import Data.Bugsnag.Types.User++data Event = Event+  { exceptions :: [Exception]+  -- ^ An array of exceptions that occurred during this event. There must be at+  -- least one entry. Most of the time there will only be one exception, but+  -- some languages support \"nested\" or \"caused by\" exceptions. In this+  -- case, exceptions should be unwrapped and added to the array one at a+  -- time. The array should be in order from the outermost error to the+  -- innermost. For example, the first element in the array should be the+  -- error caused by the second element, and so on.+  , breadcrumbs :: Maybe [Breadcrumb]+  -- ^ An array of user- and system-initiated events which led up to an error,+  -- providing additional context. This list is sequential and ordered newest+  -- to oldest.+  , request :: Maybe Request+  , threads :: Maybe [Thread]+  -- ^ An array of background threads. This is optional but recommended for+  -- apps that rely heavily on threading. Threads should be in an order that+  -- makes sense for your application.+  , context :: Maybe Text+  -- ^ A string representing what was happening in the application at the time+  -- of the error. This string could be used for grouping purposes, depending+  -- on the event. Usually this would represent the controller and action in+  -- a server based project. It could represent the screen that the user was+  -- interacting with in a client side project. For example:+  --+  -- -   On Ruby on Rails the context could be @controller#action@.+  --+  -- -   In Android, the context could be the top most Activity.+  --+  -- -   In iOS, the context could be the name of the top most+  --     UIViewController.+  , groupingHash :: Maybe Text+  -- ^ The+  -- <https://docs.bugsnag.com/product/error-grouping default error grouping>+  -- can be overridden by specifying a custom grouping hash.+  , unhandled :: Maybe Bool+  -- ^ Whether the error was unhandled. If true, the error was detected by the+  -- notifier because it was not handled by the application. If false, the+  -- errors was handled and reported using Bugsnag.notify.+  , severity :: Maybe Severity+  -- ^ The severity of the error+  --+  -- -   @error@ - The default for unhandled errors.+  --+  -- -   @warning@ - The default when Bugsnag.notify is called.+  --+  -- -   @info@ - Can be used in manual Bugsnag.notify calls.+  , severityReason :: Maybe SeverityReason+  , projectPackages :: Maybe [Text]+  -- ^ Sets which package names should be considered as a part of the running+  -- application. We mark stacktrace lines as in-project if they originate+  -- from any of these packages and this allows us to improve the visual+  -- display of the stacktrace on the dashboard.+  , user :: Maybe User+  , app :: Maybe Application+  , device :: Maybe Device+  , session :: Maybe Session+  , featureFlags :: Maybe [FeatureFlag]+  -- ^ Details of the feature flags (experiments) and associated variants that+  -- were active when the error occurred.+  , metaData :: Maybe (KeyMap (KeyMap Text))+  -- ^ An object containing any further data you wish to attach to this error+  -- event. This should contain one or more objects, with each object being+  -- displayed in its own tab on the event details on the dashboard.+  --+  -- >   {+  -- >       // Custom user data to be displayed in the User tab along with standard+  -- >       // user fields on the dashboard.+  -- >       "user": {+  -- >          ...+  -- >       },+  -- >+  -- >       // Custom app data to be displayed in the App tab along with standard+  -- >       // app fields on the dashboard.+  -- >       "app": {+  -- >          ...+  -- >       },+  -- >+  -- >       // Custom device data to be displayed in the Device tab along with+  -- >       //standard device fields on the dashboard.+  -- >       "device": {+  -- >          ...+  -- >       },+  -- >+  -- >       Custom request data to be displayed in the Request tab along with+  -- >       standard request fields on the dashboard.+  -- >       "request": {+  -- >          ...+  -- >       },+  -- >+  -- >       // This will be displayed as an extra tab on the dashboard.+  -- >       "Some data": {+  -- >+  -- >           // A key value pair that will be displayed in the first tab.+  -- >           "key": "value",+  -- >+  -- >           // Key value pairs can be contained in nested objects which helps+  -- >           // to organize the information presented in the tab.+  -- >           "setOfKeys": {+  -- >               "key": "value",+  -- >               "key2": "value"+  -- >           }+  -- >       },+  -- >+  -- >       // This would be the second extra tab on the dashboard.+  -- >       "Some more data": {+  -- >           ...+  -- >       }+  -- >   }+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Event where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Event where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultEvent :: [Exception] -> Event+defaultEvent exceptions =+  Event+    { exceptions+    , breadcrumbs = Nothing+    , request = Nothing+    , threads = Nothing+    , context = Nothing+    , groupingHash = Nothing+    , unhandled = Nothing+    , severity = Nothing+    , severityReason = Nothing+    , projectPackages = Nothing+    , user = Nothing+    , app = Nothing+    , device = Nothing+    , session = Nothing+    , featureFlags = Nothing+    , metaData = Nothing+    }++exampleEvent :: Event+exampleEvent =+  Event+    { exceptions = [exampleException]+    , breadcrumbs = Just [exampleBreadcrumb]+    , request = Just exampleRequest+    , threads = Just [exampleThread]+    , context = Just "auth/session#create"+    , groupingHash = Just "buggy_file.rb"+    , unhandled = Just True+    , severity = Just exampleSeverity+    , severityReason = Just exampleSeverityReason+    , projectPackages = Just ["com.example.package1", "com.example.package2"]+    , user = Just exampleUser+    , app = Just exampleApplication+    , device = Just exampleDevice+    , session = Just exampleSession+    , featureFlags = Just [exampleFeatureFlag]+    , metaData = Nothing+    }
+ src/Data/Bugsnag/Types/Exception.hs view
@@ -0,0 +1,54 @@+module Data.Bugsnag.Types.Exception+  ( Exception (..)+  , exampleException+  , defaultException+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.ErrorType+import Data.Bugsnag.Types.Stackframe++data Exception = Exception+  { errorClass :: Text+  -- ^ The class of error which occurred. This field is used to group the+  -- errors together so should not contain any contextual information that+  -- would prevent correct grouping. This would ordinarily be the Exception+  -- name when dealing with an exception.+  , message :: Maybe Text+  -- ^ The error message associated with the error. Usually this will contain+  -- some information about this specific instance of the error and is not+  -- used to group the errors.+  , stacktrace :: [Stackframe]+  -- ^ An array of stackframe objects. Each object represents one line in the+  -- exception\'s stacktrace. This information is used to help with error+  -- grouping, as well as displaying it to the user.+  , type_ :: Maybe ErrorType+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Exception where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Exception where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultException :: Text -> [Stackframe] -> Exception+defaultException errorClass stacktrace =+  Exception+    { errorClass+    , stacktrace+    , message = Nothing+    , type_ = Nothing+    }++exampleException :: Exception+exampleException =+  Exception+    { errorClass = "NoMethodError"+    , message = Just "Unable to connect to database"+    , stacktrace = [exampleStackframe]+    , type_ = Just exampleErrorType+    }
+ src/Data/Bugsnag/Types/FeatureFlag.hs view
@@ -0,0 +1,37 @@+module Data.Bugsnag.Types.FeatureFlag+  ( FeatureFlag (..)+  , exampleFeatureFlag+  , defaultFeatureFlag+  )+where++import Data.Bugsnag.Types.Prelude++data FeatureFlag = FeatureFlag+  { featureFlag :: Text+  -- ^ The name of the feature flag.+  , variant :: Maybe Text+  -- ^ The name of the variant.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON FeatureFlag where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON FeatureFlag where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultFeatureFlag :: Text -> FeatureFlag+defaultFeatureFlag featureFlag =+  FeatureFlag+    { featureFlag+    , variant = Nothing+    }++exampleFeatureFlag :: FeatureFlag+exampleFeatureFlag =+  FeatureFlag+    { featureFlag = "share_ios_photo_sharing_button"+    , variant = Just "blue_button"+    }
+ src/Data/Bugsnag/Types/Notifier.hs view
@@ -0,0 +1,51 @@+module Data.Bugsnag.Types.Notifier+  ( Notifier (..)+  , exampleNotifier+  , defaultNotifier+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.DependentNotifier++-- | Describes the notifier itself. These properties are used within BugSnag+-- to track error rates from a notifier.+data Notifier = Notifier+  { name :: Text+  -- ^ The notifier name.+  , version :: Text+  -- ^ The notifier\'s current version.+  , url :: Text+  -- ^ The URL associated with the notifier.+  , dependencies :: Maybe [DependentNotifier]+  -- ^ For platforms where multiple notifiers are used to capture an event, an+  -- optional array containing the details of the additional notifiers can be+  -- specified.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Notifier where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Notifier where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultNotifier :: Text -> Text -> Text -> Notifier+defaultNotifier name version url =+  Notifier+    { name+    , version+    , url+    , dependencies = Nothing+    }++exampleNotifier :: Notifier+exampleNotifier =+  Notifier+    { name = "Bugsnag Ruby"+    , version = "1.0.11"+    , url = "https://github.com/bugsnag/bugsnag-ruby"+    , dependencies = Just [exampleDependentNotifier]+    }
+ src/Data/Bugsnag/Types/Payload.hs view
@@ -0,0 +1,54 @@+module Data.Bugsnag.Types.Payload+  ( Payload (..)+  , examplePayload+  , defaultPayload+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.Event+import Data.Bugsnag.Types.Notifier++data Payload = Payload+  { apiKey :: Maybe Text+  -- ^ The API Key associated with the project. Informs BugSnag which project+  -- has generated this error. This is provided for legacy notifiers. It is+  -- preferable to use the @Bugsnag-Api-Key@ header instead.+  , payloadVersion :: Text+  -- ^ The version number of the payload. This is currently @5@. The+  -- @Bugsnag-Payload-Version@ header should be included as well for+  -- compatibility reasons.+  , notifier :: Notifier+  , events :: [Event]+  -- ^ An array of error events that BugSnag should be notified of. A notifier+  -- can choose to group notices into an array to minimize network traffic,+  -- or can notify BugSnag each time an event occurs. Should contain at least+  -- 1 event.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Payload where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Payload where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultPayload :: Text -> Notifier -> [Event] -> Payload+defaultPayload payloadVersion notifier events =+  Payload+    { payloadVersion+    , notifier+    , events+    , apiKey = Nothing+    }++examplePayload :: Payload+examplePayload =+  Payload+    { apiKey = Just "YOUR-NOTIFIER-API-KEY"+    , payloadVersion = "5"+    , notifier = exampleNotifier+    , events = [exampleEvent]+    }
+ src/Data/Bugsnag/Types/Prelude.hs view
@@ -0,0 +1,34 @@+module Data.Bugsnag.Types.Prelude+  ( module X+  , aesonOptions+  )+where++import Prelude as X hiding (id)++import Control.Monad as X (void)+import Data.Aeson (Options (..), defaultOptions)+import Data.Aeson as X+  ( FromJSON (..)+  , ToJSON (..)+  , genericParseJSON+  , genericToEncoding+  , genericToJSON+  )+import Data.Aeson.KeyMap as X (KeyMap)+import Data.Char (toLower)+import Data.Foldable as X (for_, traverse_)+import Data.Maybe as X (catMaybes, fromMaybe, mapMaybe)+import Data.Text as X (Text, pack, unpack)+import Data.Traversable as X (for)+import GHC.Generics as X (Generic)++aesonOptions :: Options+aesonOptions =+  defaultOptions+    { fieldLabelModifier = \case+        "type_" -> "type"+        x -> x+    , constructorTagModifier = map toLower+    , omitNothingFields = True+    }
+ src/Data/Bugsnag/Types/Request.hs view
@@ -0,0 +1,59 @@+module Data.Bugsnag.Types.Request+  ( Request (..)+  , exampleRequest+  , defaultRequest+  )+where++import Data.Bugsnag.Types.Prelude++-- | Details about the web request from the client that experienced the+-- error, if relevant. To display custom request data alongside these+-- standard fields on the dashboard, the custom data should be included in+-- the @metaData@ object in a @request@ object.+data Request = Request+  { clientIp :: Maybe Text+  -- ^ The IP address of the client that experienced the error.+  , headers :: Maybe (KeyMap Text)+  -- ^ The headers sent with the request.+  --+  -- > {+  -- >     "Accept": "*/*",+  -- >     "Accept-Encoding": "gzip, deflate, sdch, br",+  -- >     "Accept-Language": "en-US,en;q=0.8"+  -- > }+  , httpMethod :: Maybe Text+  -- ^ The HTTP method used.+  , url :: Maybe Text+  -- ^ The URL of the request.+  , referer :: Maybe Text+  -- ^ The <https://en.wikipedia.org/wiki/HTTP_referer HTTP referer>+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Request where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Request where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultRequest :: Request+defaultRequest =+  Request+    { clientIp = Nothing+    , headers = Nothing+    , httpMethod = Nothing+    , url = Nothing+    , referer = Nothing+    }++exampleRequest :: Request+exampleRequest =+  Request+    { clientIp = Just "192.168.44.0"+    , headers = Nothing+    , httpMethod = Just "PUT"+    , url = Just "http://example.com/users/19/settings"+    , referer = Just "http://example.com?q=awesome"+    }
+ src/Data/Bugsnag/Types/RuntimeVersion.hs view
@@ -0,0 +1,239 @@+module Data.Bugsnag.Types.RuntimeVersion+  ( RuntimeVersion (..)+  , exampleRuntimeVersion+  , defaultRuntimeVersion+  )+where++import Data.Bugsnag.Types.Prelude++-- | The versions of the relevant runtimes, languages and\/or frameworks for+-- the platform.+data RuntimeVersion = RuntimeVersion+  { androidApiLevel :: Maybe Text+  -- ^ The Android API level (Android only).+  , bottle :: Maybe Text+  -- ^ Bottle framework version (Python only).+  , celery :: Maybe Text+  -- ^ Celery task queue version (Python only).+  , clangVersion :: Maybe Text+  -- ^ Clang compiler version (iOS\/tvOS\/macOS only).+  , cocos2dx :: Maybe Text+  -- ^ Cocos2d-x framework version (Cocos2d-x only).+  , delayedJob :: Maybe Text+  -- ^ Delayed Job framework version (Ruby only).+  , django :: Maybe Text+  -- ^ Django framework version (Python only).+  , dotnet :: Maybe Text+  -- ^ Description of the framework (.NET only).+  , dotnetApiCompatibility :: Maybe Text+  -- ^ .NET API compatibility level (Unity only).+  , dotnetClr :: Maybe Text+  -- ^ Version of .NET Common Language Runtime (.NET only).+  , dotnetScriptingRuntime :: Maybe Text+  -- ^ .NET scripting runtime version (Unity only).+  , electron :: Maybe Text+  -- ^ Electron platform version (Electron only).+  , eventMachine :: Maybe Text+  -- ^ EventMachine library version (Ruby only).+  , expoApp :: Maybe Text+  -- ^ Expo app version (Expo only).+  , expoSdk :: Maybe Text+  -- ^ Expo SDK version (Expo only).+  , flask :: Maybe Text+  -- ^ Flask framework version (Python only).+  , gin :: Maybe Text+  -- ^ Gin framework version (Go only).+  , go :: Maybe Text+  -- ^ Go language version (Go only).+  , javaType :: Maybe Text+  -- ^ Java platform implementation type (Java only).+  , javaVersion :: Maybe Text+  -- ^ Java runtime version (Java only).+  , jruby :: Maybe Text+  -- ^ Version of JRuby (Ruby only).+  , laravel :: Maybe Text+  -- ^ Laravel framework version (PHP only).+  , lumen :: Maybe Text+  -- ^ Lumen framework version (PHP only).+  , magento :: Maybe Text+  -- ^ Magento platform version (PHP only).+  , mailman :: Maybe Text+  -- ^ Mailman framework version (Ruby only).+  , martini :: Maybe Text+  -- ^ Martini framework version (Go only).+  , negroni :: Maybe Text+  -- ^ Negroni framework version (Go only).+  , node :: Maybe Text+  -- ^ Node.js version (Javascript only).+  , osBuild :: Maybe Text+  -- ^ Build number of the OS (iOS\/tvOS\/macOS only).+  , php :: Maybe Text+  -- ^ Version of PHP (PHP only).+  , python :: Maybe Text+  -- ^ Version of Python (Python only).+  , que :: Maybe Text+  -- ^ Que job queue version (Ruby only).+  , rack :: Maybe Text+  -- ^ Rack webserver version (Ruby only).+  , rails :: Maybe Text+  -- ^ Ruby on Rails version (Ruby only).+  , rake :: Maybe Text+  -- ^ Rake tool version (Ruby only).+  , reactNative :: Maybe Text+  -- ^ Version of React Native (React Native\/Expo only).+  , reactNativeJsEngine :: Maybe Text+  -- ^ Javascript engine type (React Native\/Expo only).+  , resque :: Maybe Text+  -- ^ Resque library version (Ruby only).+  , revel :: Maybe Text+  -- ^ Revel framework version (Go only).+  , ruby :: Maybe Text+  -- ^ Version of Ruby (Ruby only).+  , shoryoken :: Maybe Text+  -- ^ Shoryoken framework version (Ruby only).+  , sidekiq :: Maybe Text+  -- ^ Sidekiq scheduler version (Ruby only).+  , silex :: Maybe Text+  -- ^ Silex framework version (PHP only).+  , sinatra :: Maybe Text+  -- ^ Sinatra DSL version (Ruby only).+  , springBoot :: Maybe Text+  -- ^ Spring Boot framework version (Java only).+  , springFramework :: Maybe Text+  -- ^ Spring framework version (Java only).+  , swift :: Maybe Text+  -- ^ Swift language version (iOS\/tvOS\/macOS only).+  , symfony :: Maybe Text+  -- ^ Symfony framework version (PHP only).+  , tornado :: Maybe Text+  -- ^ Tornado framework version (Python only).+  , unity :: Maybe Text+  -- ^ Version of Unity.+  , unityScriptingBackend :: Maybe Text+  -- ^ The Unity scripting backend - Mono or IL2CPP (Unity only).+  , wordpress :: Maybe Text+  -- ^ Wordpress version (PHP only).+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON RuntimeVersion where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON RuntimeVersion where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultRuntimeVersion :: RuntimeVersion+defaultRuntimeVersion =+  RuntimeVersion+    { androidApiLevel = Nothing+    , bottle = Nothing+    , celery = Nothing+    , clangVersion = Nothing+    , cocos2dx = Nothing+    , delayedJob = Nothing+    , django = Nothing+    , dotnet = Nothing+    , dotnetApiCompatibility = Nothing+    , dotnetClr = Nothing+    , dotnetScriptingRuntime = Nothing+    , electron = Nothing+    , eventMachine = Nothing+    , expoApp = Nothing+    , expoSdk = Nothing+    , flask = Nothing+    , gin = Nothing+    , go = Nothing+    , javaType = Nothing+    , javaVersion = Nothing+    , jruby = Nothing+    , laravel = Nothing+    , lumen = Nothing+    , magento = Nothing+    , mailman = Nothing+    , martini = Nothing+    , negroni = Nothing+    , node = Nothing+    , osBuild = Nothing+    , php = Nothing+    , python = Nothing+    , que = Nothing+    , rack = Nothing+    , rails = Nothing+    , rake = Nothing+    , reactNative = Nothing+    , reactNativeJsEngine = Nothing+    , resque = Nothing+    , revel = Nothing+    , ruby = Nothing+    , shoryoken = Nothing+    , sidekiq = Nothing+    , silex = Nothing+    , sinatra = Nothing+    , springBoot = Nothing+    , springFramework = Nothing+    , swift = Nothing+    , symfony = Nothing+    , tornado = Nothing+    , unity = Nothing+    , unityScriptingBackend = Nothing+    , wordpress = Nothing+    }++exampleRuntimeVersion :: RuntimeVersion+exampleRuntimeVersion =+  RuntimeVersion+    { androidApiLevel = Just "28"+    , bottle = Just "0.12.8"+    , celery = Just "4.2.0"+    , clangVersion = Just "7.0.1"+    , cocos2dx = Just "3.17.2"+    , delayedJob = Just "4.1.8"+    , django = Just "2.1.7"+    , dotnet = Just ".NET Framework 4.7.3416.0"+    , dotnetApiCompatibility = Just ".NET 2.0 Subset"+    , dotnetClr = Just "4.0.30319.17379"+    , dotnetScriptingRuntime = Just ".NET 3.5 equivalent"+    , electron = Just "11.4.3"+    , eventMachine = Just "1.2.7"+    , expoApp = Just "2.10.0.105125"+    , expoSdk = Just "32.0.0"+    , flask = Just "1.0.2"+    , gin = Just "1.3.0"+    , go = Just "1.11.2"+    , javaType = Just "Java(TM) SE Runtime Environment"+    , javaVersion = Just "1.8.0_131-b11"+    , jruby = Just "9.2.5.0"+    , laravel = Just "5.7.22"+    , lumen = Just "5.7"+    , magento = Just "2.3.0"+    , mailman = Just "0.8.0"+    , martini = Just "1.0"+    , negroni = Just "1.0.0"+    , node = Just "10.14.1"+    , osBuild = Just "16D57"+    , php = Just "7.2.12"+    , python = Just "3.7.1"+    , que = Just "0.14.3"+    , rack = Just "2.0.6"+    , rails = Just "5.2.2"+    , rake = Just "12.3.2"+    , reactNative = Just "0.57.5"+    , reactNativeJsEngine = Just "hermes"+    , resque = Just "2.0.0"+    , revel = Just "0.21.0"+    , ruby = Just "2.5.3"+    , shoryoken = Just "5.0.1"+    , sidekiq = Just "5.1.3"+    , silex = Just "2.1.0"+    , sinatra = Just "2.0.3"+    , springBoot = Just "1.5.13.RELEASE"+    , springFramework = Just "4.2.13.RELEASE"+    , swift = Just "4.2"+    , symfony = Just "4.2.11"+    , tornado = Just "5.1.1"+    , unity = Just "2018.2.17"+    , unityScriptingBackend = Just "Mono"+    , wordpress = Just "5.1"+    }
+ src/Data/Bugsnag/Types/Session.hs view
@@ -0,0 +1,49 @@+module Data.Bugsnag.Types.Session+  ( Session (..)+  , exampleSession+  , defaultSession+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.SessionEvent++-- | Details of any session information associated with the event.+--+-- This can be used alongside the+-- <https://smartbear.portal.swaggerhub.com/bugsnag/default/bugsnag-session-reporting-api Session Tracking API>+-- to associate the event with a session so that a release\'s crash rate+-- can be determined.+data Session = Session+  { id :: Text+  -- ^ The unique identifier of the session.+  , startedAt :: Text+  -- ^ The time (in <https://en.wikipedia.org/wiki/ISO_8601 ISO 8601> format)+  -- at which the session started.+  , events :: SessionEvent+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Session where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Session where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultSession :: Text -> Text -> SessionEvent -> Session+defaultSession id startedAt events =+  Session+    { id+    , startedAt+    , events+    }++exampleSession :: Session+exampleSession =+  Session+    { id = "9f65c975-8155-456f-91e5-c4c4b3db0555"+    , startedAt = "2017-01-01T14:30:00.000Z"+    , events = exampleSessionEvent+    }
+ src/Data/Bugsnag/Types/SessionEvent.hs view
@@ -0,0 +1,41 @@+module Data.Bugsnag.Types.SessionEvent+  ( SessionEvent (..)+  , exampleSessionEvent+  , defaultSessionEvent+  )+where++import Data.Bugsnag.Types.Prelude++-- | Details of the number of handled and unhandled events that have occurred+-- so far in this session.+data SessionEvent = SessionEvent+  { handled :: Int+  -- ^ The number of handled events that have occurred in this session+  -- (including this event).+  , unhandled :: Int+  -- ^ The number of unhandled events that have occurred in this session+  -- (including this event)+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON SessionEvent where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON SessionEvent where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultSessionEvent :: Int -> Int -> SessionEvent+defaultSessionEvent handled unhandled =+  SessionEvent+    { handled+    , unhandled+    }++exampleSessionEvent :: SessionEvent+exampleSessionEvent =+  SessionEvent+    { handled = 1+    , unhandled = 1+    }
+ src/Data/Bugsnag/Types/Severity.hs view
@@ -0,0 +1,30 @@+module Data.Bugsnag.Types.Severity+  ( Severity (..)+  , exampleSeverity+  )+where++import Data.Bugsnag.Types.Prelude++-- | The severity of the error+--+-- -   @error@ - The default for unhandled errors.+--+-- -   @warning@ - The default when Bugsnag.notify is called.+--+-- -   @info@ - Can be used in manual Bugsnag.notify calls.+data Severity+  = Error+  | Warning+  | Info+  deriving stock (Bounded, Enum, Eq, Generic, Show)++instance FromJSON Severity where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Severity where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++exampleSeverity :: Severity+exampleSeverity = Error
+ src/Data/Bugsnag/Types/SeverityReason.hs view
@@ -0,0 +1,82 @@+module Data.Bugsnag.Types.SeverityReason+  ( SeverityReason (..)+  , exampleSeverityReason+  , defaultSeverityReason+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.SeverityReasonAttributes+import Data.Bugsnag.Types.SeverityReasonType++-- | Information about why the severity was picked.+data SeverityReason = SeverityReason+  { type_ :: Maybe SeverityReasonType+  -- ^ A type key that represents the reason for the assigned severity.+  --+  -- -   @unhandledException@- Whenever an uncaught exception is discovered+  --     (generic).+  -- -   @unhandledError@ - When an error is discovered (PHP).+  -- -   @log@ - Whenever a log message is sent (generic).+  -- -   @signal@ - Whenever a \"fatal\" signal is discovered (iOS).+  -- -   @strictMode@ - Whenever a strictMode issue is discovered (Android).+  -- -   @unhandledPromiseRejection@ Whenever an unhandled promise rejection+  --     is discovered (JS\/Node JS\/React Native).+  -- -   @callbackErrorIntercept@- callbackErrorIntercept (Node JS).+  -- -   @errorClass@ - Whenever an exception with a particular class is+  --     automatically sent (Ruby).+  -- -   @exceptionClass@ - Whenever an exception with a particular class is+  --     automatically sent (Java).+  -- -   @unhandledPanic@ - When a panic is unhandled and crashes the app+  --     (Go).+  -- -   @unhandledErrorMiddleware@ - Unhandled errors in ${Negroni}+  --     middleware have a default severity:error.+  -- -   @unhandledExceptionMiddleware@ - Unhandled exceptions in ${Rack}+  --     middleware have a default severity:error.+  -- -   @userCallbackSetSeverity@ - Whenever a callback changes a report\'s+  --     severity (generic).+  -- -   @userSpecifiedSeverity@ - Whenever a severity is set through a+  --     manual notify call (generic).+  -- -   @handledException@ - Whenever a handled exception is sent through+  --     (generic).+  -- -   @handledError@ - Whenever a handled error is sent through (PHP).+  -- -   @handledPanic@ - Whenever a panic is handled through AutoNotify or+  --     Recover (Go).+  -- -   @userContextSetSeverity@ - When a user creates a context which+  --     changes the severity (Python).+  -- -   @anrError@ - Whenever an ANR is detected (Android).+  -- -   @appHang@ - Whenever an app hang is detected (Cocoa).+  -- -   @outOfMemory@ - When an app is terminated because it used too much+  --     memory (Cocoa).+  -- -   @thermalKill@ - When an app is terminated because the device is+  --     overheating (Cocoa).+  , attributes :: Maybe SeverityReasonAttributes+  , unhandledOverridden :: Maybe Bool+  -- ^ Whether the event\'s @unhandled@ flag was overridden from the+  -- notifier\'s default value.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON SeverityReason where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON SeverityReason where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultSeverityReason :: SeverityReason+defaultSeverityReason =+  SeverityReason+    { type_ = Nothing+    , attributes = Nothing+    , unhandledOverridden = Nothing+    }++exampleSeverityReason :: SeverityReason+exampleSeverityReason =+  SeverityReason+    { type_ = Just exampleSeverityReasonType+    , attributes = Just exampleSeverityReasonAttributes+    , unhandledOverridden = Just False+    }
+ src/Data/Bugsnag/Types/SeverityReasonAttributes.hs view
@@ -0,0 +1,65 @@+module Data.Bugsnag.Types.SeverityReasonAttributes+  ( SeverityReasonAttributes (..)+  , exampleSeverityReasonAttributes+  , defaultSeverityReasonAttributes+  )+where++import Data.Bugsnag.Types.Prelude++-- | Optional attributes to provide extra information about the severity+-- reason.+data SeverityReasonAttributes = SeverityReasonAttributes+  { errorType :: Maybe Text+  -- ^ Included for @unhandledError@ severity reason. See+  -- <http://php.net/manual/en/errorfunc.constants.php PHP Error Constants>.+  , level :: Maybe Text+  -- ^ Included for @log@ severity reason.+  , signalType :: Maybe Text+  -- ^ Included for @signal@ severity reason. See+  -- <https://en.wikipedia.org/wiki/C_signal_handling Signal Codes>.+  , violationType :: Maybe Text+  -- ^ Included for @strictMode@ severity reason. See+  -- <https://developer.android.com/reference/android/os/StrictMode.html Strict Mode>.+  , errorClass :: Maybe Text+  -- ^ Included for @errorClass@ severity reason. Specifies the error class+  -- that is automatically sent.+  , framework :: Maybe Text+  -- ^ Included for middleware severity reasons, specifies the middleware that+  -- had an error.+  , exceptionClass :: Maybe Text+  -- ^ Included for @exceptionClass@ severity reason. Specifies the error class+  -- that is automatically sent.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON SeverityReasonAttributes where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON SeverityReasonAttributes where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultSeverityReasonAttributes :: SeverityReasonAttributes+defaultSeverityReasonAttributes =+  SeverityReasonAttributes+    { errorType = Nothing+    , level = Nothing+    , signalType = Nothing+    , violationType = Nothing+    , errorClass = Nothing+    , framework = Nothing+    , exceptionClass = Nothing+    }++exampleSeverityReasonAttributes :: SeverityReasonAttributes+exampleSeverityReasonAttributes =+  SeverityReasonAttributes+    { errorType = Just "E_ERROR"+    , level = Just "Error"+    , signalType = Just "SIGSEGV"+    , violationType = Just "NetworkOnMainThread"+    , errorClass = Just "ActiveRecord::RecordNotFound"+    , framework = Just "Rack"+    , exceptionClass = Just "TypeMismatchException"+    }
+ src/Data/Bugsnag/Types/SeverityReasonType.hs view
@@ -0,0 +1,80 @@+module Data.Bugsnag.Types.SeverityReasonType+  ( SeverityReasonType (..)+  , exampleSeverityReasonType+  )+where++import Data.Bugsnag.Types.Prelude++-- | A type key that represents the reason for the assigned severity.+--+-- -   @unhandledException@- Whenever an uncaught exception is discovered+--     (generic).+-- -   @unhandledError@ - When an error is discovered (PHP).+-- -   @log@ - Whenever a log message is sent (generic).+-- -   @signal@ - Whenever a \"fatal\" signal is discovered (iOS).+-- -   @strictMode@ - Whenever a strictMode issue is discovered (Android).+-- -   @unhandledPromiseRejection@ Whenever an unhandled promise rejection+--     is discovered (JS\/Node JS\/React Native).+-- -   @callbackErrorIntercept@- callbackErrorIntercept (Node JS).+-- -   @errorClass@ - Whenever an exception with a particular class is+--     automatically sent (Ruby).+-- -   @exceptionClass@ - Whenever an exception with a particular class is+--     automatically sent (Java).+-- -   @unhandledPanic@ - When a panic is unhandled and crashes the app+--     (Go).+-- -   @unhandledErrorMiddleware@ - Unhandled errors in ${Negroni}+--     middleware have a default severity:error.+-- -   @unhandledExceptionMiddleware@ - Unhandled exceptions in ${Rack}+--     middleware have a default severity:error.+-- -   @userCallbackSetSeverity@ - Whenever a callback changes a report\'s+--     severity (generic).+-- -   @userSpecifiedSeverity@ - Whenever a severity is set through a+--     manual notify call (generic).+-- -   @handledException@ - Whenever a handled exception is sent through+--     (generic).+-- -   @handledError@ - Whenever a handled error is sent through (PHP).+-- -   @handledPanic@ - Whenever a panic is handled through AutoNotify or+--     Recover (Go).+-- -   @userContextSetSeverity@ - When a user creates a context which+--     changes the severity (Python).+-- -   @anrError@ - Whenever an ANR is detected (Android).+-- -   @appHang@ - Whenever an app hang is detected (Cocoa).+-- -   @outOfMemory@ - When an app is terminated because it used too much+--     memory (Cocoa).+-- -   @thermalKill@ - When an app is terminated because the device is+--     overheating (Cocoa).+data SeverityReasonType+  = UnhandledException+  | UnhandledError+  | Log+  | Signal+  | StrictMode+  | UnhandledPromiseRejection+  | CallbackErrorIntercept+  | ErrorClass+  | ExceptionClass+  | UnhandledPanic+  | UnhandledErrorMiddleware+  | UnhandledExceptionMiddleware+  | UserCallbackSetSeverity+  | UserSpecifiedSeverity+  | HandledException+  | HandledError+  | HandledPanic+  | UserContextSetSeverity+  | AnrError+  | AppHang+  | OutOfMemory+  | ThermalKill+  deriving stock (Bounded, Enum, Eq, Generic, Show)++instance FromJSON SeverityReasonType where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON SeverityReasonType where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++exampleSeverityReasonType :: SeverityReasonType+exampleSeverityReasonType = UnhandledException
+ src/Data/Bugsnag/Types/Stackframe.hs view
@@ -0,0 +1,108 @@+module Data.Bugsnag.Types.Stackframe+  ( Stackframe (..)+  , exampleStackframe+  , defaultStackframe+  )+where++import Data.Bugsnag.Types.Prelude++data Stackframe = Stackframe+  { file :: Text+  -- ^ The file that this stack frame was executing. It is recommended that you+  -- strip any unnecessary or common information from the beginning of the+  -- path.+  , lineNumber :: Int+  -- ^ The line of the file that this frame of the stack was in.+  , columnNumber :: Maybe Int+  -- ^ The column of the file that this frame of the stack was in.+  , method :: Text+  -- ^ The method that this particular stack frame is within.+  , inProject :: Maybe Bool+  -- ^ If this stacktrace line is in the user\'s project code, set this to+  -- true. It is useful for developers to be able to see which lines of a+  -- stacktrace are within their own application, and which are within third+  -- party libraries. This information is shown in the stacktrace on the+  -- dashboard and is used to help group errors better.+  , code :: Maybe (KeyMap Text)+  , frameAddress :: Maybe Text+  -- ^ The run time memory address of the instruction being executed (for the+  -- first stack frame) or to which control will return after the function+  -- call or subroutine completes.+  , loadAddress :: Maybe Text+  -- ^ The address in memory where the binary has been loaded at run time.+  , isLR :: Maybe Bool+  -- ^ True if @frameAddress@ corresponds to value of the Link Register. This+  -- is sometimes the case for the second frame in a stack - e.g. for signals+  -- and mach exceptions.+  , isPC :: Maybe Bool+  -- ^ True if @frameAddress@ corresponds to the Program Counter.+  , symbolAddress :: Maybe Text+  -- ^ The run time memory address of the symbol that most closely matches+  -- @frameAddress@.+  , machoFile :: Maybe Text+  -- ^ The full path of the Mach-O binary (iOS\/macOS\/tvOS only).+  , machoLoadAddress :: Maybe Text+  -- ^ The address in memory where the Mach-O binary has been loaded at run+  -- time. This may differ from @machoVMAddress@ due to Address Space Layout+  -- Randomization. The difference between @machoLoadAddress@ and+  -- @machoVMAddress@ is known as the \"slide\" (iOS\/macOS\/tvOS only).+  , machoUUID :: Maybe Text+  -- ^ A UUID which uniquely identifies this Mach-O binary (iOS\/macOS\/tvOS+  -- only).+  , machoVMAddress :: Maybe Text+  -- ^ The memory address assigned to the Mach-O binary by the linker at build+  -- time (iOS\/macOS\/tvOS only).+  , codeIdentifier :: Maybe Text+  -- ^ The ID of the executable\/library that the frame relates to.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Stackframe where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Stackframe where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultStackframe :: Text -> Int -> Text -> Stackframe+defaultStackframe file lineNumber method =+  Stackframe+    { file+    , lineNumber+    , method+    , columnNumber = Nothing+    , inProject = Nothing+    , code = Nothing+    , frameAddress = Nothing+    , loadAddress = Nothing+    , isLR = Nothing+    , isPC = Nothing+    , symbolAddress = Nothing+    , machoFile = Nothing+    , machoLoadAddress = Nothing+    , machoUUID = Nothing+    , machoVMAddress = Nothing+    , codeIdentifier = Nothing+    }++exampleStackframe :: Stackframe+exampleStackframe =+  Stackframe+    { file = "controllers/auth/session_controller.rb"+    , lineNumber = 1234+    , columnNumber = Just 123+    , method = "create"+    , inProject = Just True+    , code = Nothing+    , frameAddress = Just "0x000000010d131040"+    , loadAddress = Just "0x000000010d12e000"+    , isLR = Nothing+    , isPC = Just True+    , symbolAddress = Just "0x000000010d130fe6"+    , machoFile = Just "/System/Library/Frameworks/Foundation.framework/Foundation"+    , machoLoadAddress = Just "0x000000010d12e000"+    , machoUUID = Just "B3196052-BAF1-3EA5-AD28-F9E6ECCF0B03"+    , machoVMAddress = Just "0x0000000100000000"+    , codeIdentifier = Just "b6b529d5e58421a0fba0fa2c5c2c5f3e"+    }
+ src/Data/Bugsnag/Types/Thread.hs view
@@ -0,0 +1,57 @@+module Data.Bugsnag.Types.Thread+  ( Thread (..)+  , exampleThread+  , defaultThread+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Bugsnag.Types.ErrorType+import Data.Bugsnag.Types.Stackframe++data Thread = Thread+  { id :: Maybe Text+  -- ^ The id of the thread in your application.+  , name :: Maybe Text+  -- ^ A human readable name for the thread.+  , errorReportingThread :: Maybe Bool+  -- ^ If this is the thread that the error was reported from (either an+  -- unhandled error or a call to bugsnag.notify), set this to true.+  , stacktrace :: Maybe [Stackframe]+  -- ^ An array of stacktrace objects. Each object represents one line in the+  -- stacktrace of the thread at the point that the error occurred.+  , state :: Maybe Text+  -- ^ The state of the thread at the time of the error.+  , type_ :: Maybe ErrorType+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON Thread where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON Thread where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultThread :: Thread+defaultThread =+  Thread+    { id = Nothing+    , name = Nothing+    , errorReportingThread = Nothing+    , stacktrace = Nothing+    , state = Nothing+    , type_ = Nothing+    }++exampleThread :: Thread+exampleThread =+  Thread+    { id = Just "thread_id"+    , name = Just "thread_name"+    , errorReportingThread = Just True+    , stacktrace = Just [exampleStackframe]+    , state = Just "WAITING"+    , type_ = Just exampleErrorType+    }
+ src/Data/Bugsnag/Types/User.hs view
@@ -0,0 +1,46 @@+module Data.Bugsnag.Types.User+  ( User (..)+  , exampleUser+  , defaultUser+  )+where++import Data.Bugsnag.Types.Prelude++-- | Information about the user affected by the error. These fields are+-- optional but highly recommended. To display custom user data alongside+-- these standard fields on the dashboard, the custom data should be+-- included in the @metaData@ object in a @user@ object.+data User = User+  { id :: Maybe Text+  -- ^ A unique identifier for a user affected by this event. This could be any+  -- distinct identifier that makes sense for your application\/platform.+  , name :: Maybe Text+  -- ^ The user\'s name, or a string you use to identify them.+  , email :: Maybe Text+  -- ^ The user\'s email address.+  }+  deriving stock (Eq, Generic, Show)++instance FromJSON User where+  parseJSON = genericParseJSON aesonOptions++instance ToJSON User where+  toJSON = genericToJSON aesonOptions+  toEncoding = genericToEncoding aesonOptions++defaultUser :: User+defaultUser =+  User+    { id = Nothing+    , name = Nothing+    , email = Nothing+    }++exampleUser :: User+exampleUser =+  User+    { id = Just "19"+    , name = Just "Robert Hawkins"+    , email = Just "bob@example.com"+    }
+ test/Data/Bugsnag/Types/PayloadSpec.hs view
@@ -0,0 +1,179 @@+module Data.Bugsnag.Types.PayloadSpec+  ( spec+  )+where++import Data.Bugsnag.Types.Prelude++import Data.Aeson+import Data.Bugsnag.Types.Payload+import Test.Hspec++spec :: Spec+spec = do+  describe "ToJSON" $ do+    it "renders" $ do+      encode examplePayload+        `shouldBe` mconcat+          [ "{\"apiKey\":\"YOUR-NOTIFIER-API-KEY\""+          , ",\"payloadVersion\":\"5\""+          , ",\"notifier\":{\"name\":\"Bugsnag Ruby\""+          , ",\"version\":\"1.0.11\""+          , ",\"url\":\"https://github.com/bugsnag/bugsnag-ruby\""+          , ",\"dependencies\":[{\"name\":\"Bugsnag Android\""+          , ",\"version\":\"2.1.10\""+          , ",\"url\":\"https://github.com/bugsnag/bugsnag-android\"}]}"+          , ",\"events\":[{\"exceptions\":[{\"errorClass\":\"NoMethodError\""+          , ",\"message\":\"Unable to connect to database\""+          , ",\"stacktrace\":[{\"file\":\"controllers/auth/session_controller.rb\""+          , ",\"lineNumber\":1234"+          , ",\"columnNumber\":123"+          , ",\"method\":\"create\""+          , ",\"inProject\":true"+          , ",\"frameAddress\":\"0x000000010d131040\""+          , ",\"loadAddress\":\"0x000000010d12e000\""+          , ",\"isPC\":true"+          , ",\"symbolAddress\":\"0x000000010d130fe6\""+          , ",\"machoFile\":\"/System/Library/Frameworks/Foundation.framework/Foundation\""+          , ",\"machoLoadAddress\":\"0x000000010d12e000\""+          , ",\"machoUUID\":\"B3196052-BAF1-3EA5-AD28-F9E6ECCF0B03\""+          , ",\"machoVMAddress\":\"0x0000000100000000\""+          , ",\"codeIdentifier\":\"b6b529d5e58421a0fba0fa2c5c2c5f3e\"}]"+          , ",\"type\":\"android\"}]"+          , ",\"breadcrumbs\":[{\"timestamp\":\"2016-07-19T12:17:27-0700\""+          , ",\"name\":\"Open menu\""+          , ",\"type\":\"navigation\"}]"+          , ",\"request\":{\"clientIp\":\"192.168.44.0\""+          , ",\"httpMethod\":\"PUT\""+          , ",\"url\":\"http://example.com/users/19/settings\""+          , ",\"referer\":\"http://example.com?q=awesome\"}"+          , ",\"threads\":[{\"id\":\"thread_id\""+          , ",\"name\":\"thread_name\""+          , ",\"errorReportingThread\":true"+          , ",\"stacktrace\":[{\"file\":\"controllers/auth/session_controller.rb\""+          , ",\"lineNumber\":1234"+          , ",\"columnNumber\":123"+          , ",\"method\":\"create\""+          , ",\"inProject\":true"+          , ",\"frameAddress\":\"0x000000010d131040\""+          , ",\"loadAddress\":\"0x000000010d12e000\""+          , ",\"isPC\":true"+          , ",\"symbolAddress\":\"0x000000010d130fe6\""+          , ",\"machoFile\":\"/System/Library/Frameworks/Foundation.framework/Foundation\""+          , ",\"machoLoadAddress\":\"0x000000010d12e000\""+          , ",\"machoUUID\":\"B3196052-BAF1-3EA5-AD28-F9E6ECCF0B03\""+          , ",\"machoVMAddress\":\"0x0000000100000000\""+          , ",\"codeIdentifier\":\"b6b529d5e58421a0fba0fa2c5c2c5f3e\"}]"+          , ",\"state\":\"WAITING\""+          , ",\"type\":\"android\"}]"+          , ",\"context\":\"auth/session#create\""+          , ",\"groupingHash\":\"buggy_file.rb\""+          , ",\"unhandled\":true"+          , ",\"severity\":\"error\""+          , ",\"severityReason\":{\"type\":\"unhandledexception\""+          , ",\"attributes\":{\"errorType\":\"E_ERROR\""+          , ",\"level\":\"Error\""+          , ",\"signalType\":\"SIGSEGV\""+          , ",\"violationType\":\"NetworkOnMainThread\""+          , ",\"errorClass\":\"ActiveRecord::RecordNotFound\""+          , ",\"framework\":\"Rack\""+          , ",\"exceptionClass\":\"TypeMismatchException\"}"+          , ",\"unhandledOverridden\":false}"+          , ",\"projectPackages\":[\"com.example.package1\""+          , ",\"com.example.package2\"]"+          , ",\"user\":{\"id\":\"19\""+          , ",\"name\":\"Robert Hawkins\""+          , ",\"email\":\"bob@example.com\"}"+          , ",\"app\":{\"id\":\"com.bugsnag.android.example.debug\""+          , ",\"version\":\"1.1.3\""+          , ",\"versionCode\":12"+          , ",\"bundleVersion\":\"1.0.2\""+          , ",\"codeBundleId\":\"1.0-1234\""+          , ",\"buildUUID\":\"BE5BA3D0-971C-4418-9ECF-E2D1ABCB66BE\""+          , ",\"releaseStage\":\"staging\""+          , ",\"type\":\"rails\""+          , ",\"dsymUUIDs\":[\"e6173678256785afd940392abee\"]"+          , ",\"duration\":1275"+          , ",\"durationInForeground\":983"+          , ",\"inForeground\":true"+          , ",\"isLaunching\":true"+          , ",\"binaryArch\":\"x86\""+          , ",\"runningOnRosetta\":true}"+          , ",\"device\":{\"hostname\":\"web1.internal\""+          , ",\"id\":\"fd124e87760c4281aef\""+          , ",\"manufacturer\":\"LGE\""+          , ",\"model\":\"Nexus 6P\""+          , ",\"modelNumber\":\"600\""+          , ",\"osName\":\"android\""+          , ",\"osVersion\":\"8.0.1\""+          , ",\"freeMemory\":183879616"+          , ",\"totalMemory\":201326592"+          , ",\"freeDisk\":13478064128"+          , ",\"browserName\":\"Chrome\""+          , ",\"browserVersion\":\"61.0.3163.100\""+          , ",\"orientation\":\"portrait\""+          , ",\"time\":\"2018-08-07T10:16:34.564Z\""+          , ",\"cpuAbi\":[\"x86_64\"]"+          , ",\"runtimeVersions\":{\"androidApiLevel\":\"28\""+          , ",\"bottle\":\"0.12.8\""+          , ",\"celery\":\"4.2.0\""+          , ",\"clangVersion\":\"7.0.1\""+          , ",\"cocos2dx\":\"3.17.2\""+          , ",\"delayedJob\":\"4.1.8\""+          , ",\"django\":\"2.1.7\""+          , ",\"dotnet\":\".NET Framework 4.7.3416.0\""+          , ",\"dotnetApiCompatibility\":\".NET 2.0 Subset\""+          , ",\"dotnetClr\":\"4.0.30319.17379\""+          , ",\"dotnetScriptingRuntime\":\".NET 3.5 equivalent\""+          , ",\"electron\":\"11.4.3\""+          , ",\"eventMachine\":\"1.2.7\""+          , ",\"expoApp\":\"2.10.0.105125\""+          , ",\"expoSdk\":\"32.0.0\""+          , ",\"flask\":\"1.0.2\""+          , ",\"gin\":\"1.3.0\""+          , ",\"go\":\"1.11.2\""+          , ",\"javaType\":\"Java(TM) SE Runtime Environment\""+          , ",\"javaVersion\":\"1.8.0_131-b11\""+          , ",\"jruby\":\"9.2.5.0\""+          , ",\"laravel\":\"5.7.22\""+          , ",\"lumen\":\"5.7\""+          , ",\"magento\":\"2.3.0\""+          , ",\"mailman\":\"0.8.0\""+          , ",\"martini\":\"1.0\""+          , ",\"negroni\":\"1.0.0\""+          , ",\"node\":\"10.14.1\""+          , ",\"osBuild\":\"16D57\""+          , ",\"php\":\"7.2.12\""+          , ",\"python\":\"3.7.1\""+          , ",\"que\":\"0.14.3\""+          , ",\"rack\":\"2.0.6\""+          , ",\"rails\":\"5.2.2\""+          , ",\"rake\":\"12.3.2\""+          , ",\"reactNative\":\"0.57.5\""+          , ",\"reactNativeJsEngine\":\"hermes\""+          , ",\"resque\":\"2.0.0\""+          , ",\"revel\":\"0.21.0\""+          , ",\"ruby\":\"2.5.3\""+          , ",\"shoryoken\":\"5.0.1\""+          , ",\"sidekiq\":\"5.1.3\""+          , ",\"silex\":\"2.1.0\""+          , ",\"sinatra\":\"2.0.3\""+          , ",\"springBoot\":\"1.5.13.RELEASE\""+          , ",\"springFramework\":\"4.2.13.RELEASE\""+          , ",\"swift\":\"4.2\""+          , ",\"symfony\":\"4.2.11\""+          , ",\"tornado\":\"5.1.1\""+          , ",\"unity\":\"2018.2.17\""+          , ",\"unityScriptingBackend\":\"Mono\""+          , ",\"wordpress\":\"5.1\"}"+          , ",\"macCatalystiOSVersion\":\"14.0\"}"+          , ",\"session\":{\"id\":\"9f65c975-8155-456f-91e5-c4c4b3db0555\""+          , ",\"startedAt\":\"2017-01-01T14:30:00.000Z\""+          , ",\"events\":{\"handled\":1"+          , ",\"unhandled\":1}}"+          , ",\"featureFlags\":[{\"featureFlag\":\"share_ios_photo_sharing_button\""+          , ",\"variant\":\"blue_button\"}]}]}"+          ]++    it "round-trips" $ do+      eitherDecode (encode examplePayload) `shouldBe` Right examplePayload
+ test/Spec.hs view
@@ -0,0 +1,2 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}+{-# OPTIONS_GHC -Wno-missing-export-lists #-}