restforce 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +9 -9
- data/.github/ISSUE_TEMPLATE/unhandled-salesforce-error.md +17 -0
- data/.rubocop.yml +4 -3
- data/.rubocop_todo.yml +2 -2
- data/CHANGELOG.md +36 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -1
- data/README.md +71 -33
- data/UPGRADING.md +38 -0
- data/lib/restforce.rb +11 -13
- data/lib/restforce/collection.rb +5 -0
- data/lib/restforce/concerns/api.rb +1 -1
- data/lib/restforce/concerns/authentication.rb +10 -0
- data/lib/restforce/concerns/base.rb +2 -0
- data/lib/restforce/concerns/caching.rb +7 -0
- data/lib/restforce/concerns/connection.rb +3 -3
- data/lib/restforce/concerns/streaming.rb +22 -7
- data/lib/restforce/config.rb +6 -0
- data/lib/restforce/error_code.rb +406 -0
- data/lib/restforce/file_part.rb +24 -0
- data/lib/restforce/mash.rb +1 -1
- data/lib/restforce/middleware/authentication.rb +7 -3
- data/lib/restforce/middleware/authentication/jwt_bearer.rb +38 -0
- data/lib/restforce/middleware/caching.rb +1 -1
- data/lib/restforce/middleware/instance_url.rb +1 -1
- data/lib/restforce/middleware/raise_error.rb +3 -4
- data/lib/restforce/version.rb +1 -1
- data/restforce.gemspec +14 -14
- data/spec/fixtures/test_private.key +27 -0
- data/spec/integration/abstract_client_spec.rb +18 -6
- data/spec/spec_helper.rb +14 -1
- data/spec/support/fixture_helpers.rb +1 -3
- data/spec/unit/collection_spec.rb +18 -0
- data/spec/unit/concerns/api_spec.rb +1 -1
- data/spec/unit/concerns/authentication_spec.rb +35 -0
- data/spec/unit/concerns/caching_spec.rb +26 -0
- data/spec/unit/concerns/connection_spec.rb +2 -2
- data/spec/unit/concerns/streaming_spec.rb +58 -30
- data/spec/unit/error_code_spec.rb +61 -0
- data/spec/unit/mash_spec.rb +5 -0
- data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +62 -0
- data/spec/unit/middleware/authentication_spec.rb +27 -4
- data/spec/unit/middleware/raise_error_spec.rb +19 -10
- data/spec/unit/signed_request_spec.rb +1 -1
- data/spec/unit/sobject_spec.rb +2 -5
- metadata +41 -31
- data/lib/restforce/upload_io.rb +0 -9
data/lib/restforce/collection.rb
CHANGED
@@ -19,6 +19,8 @@ module Restforce
|
|
19
19
|
Restforce::Middleware::Authentication::Password
|
20
20
|
elsif oauth_refresh?
|
21
21
|
Restforce::Middleware::Authentication::Token
|
22
|
+
elsif jwt?
|
23
|
+
Restforce::Middleware::Authentication::JWTBearer
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -38,6 +40,14 @@ module Restforce
|
|
38
40
|
options[:client_id] &&
|
39
41
|
options[:client_secret]
|
40
42
|
end
|
43
|
+
|
44
|
+
# Internal: Returns true if jwt bearer token flow should be used for
|
45
|
+
# authentication.
|
46
|
+
def jwt?
|
47
|
+
options[:jwt_key] &&
|
48
|
+
options[:username] &&
|
49
|
+
options[:client_id]
|
50
|
+
end
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
@@ -28,6 +28,8 @@ module Restforce
|
|
28
28
|
# password and oauth authentication
|
29
29
|
# :client_secret - The oauth client secret to use.
|
30
30
|
#
|
31
|
+
# :jwt_key - The private key for JWT authentication
|
32
|
+
#
|
31
33
|
# :host - The String hostname to use during
|
32
34
|
# authentication requests
|
33
35
|
# (default: 'login.salesforce.com').
|
@@ -72,9 +72,9 @@ module Restforce
|
|
72
72
|
# Internal: Faraday Connection options
|
73
73
|
def connection_options
|
74
74
|
{ request: {
|
75
|
-
|
76
|
-
|
77
|
-
},
|
75
|
+
timeout: options[:timeout],
|
76
|
+
open_timeout: options[:timeout]
|
77
|
+
},
|
78
78
|
proxy: options[:proxy_uri],
|
79
79
|
ssl: options[:ssl] }
|
80
80
|
end
|
@@ -5,13 +5,28 @@ module Restforce
|
|
5
5
|
module Streaming
|
6
6
|
# Public: Subscribe to a PushTopic
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# topics - The name of the PushTopic channel(s) to subscribe to.
|
9
9
|
# block - A block to run when a new message is received.
|
10
10
|
#
|
11
11
|
# Returns a Faye::Subscription
|
12
|
-
def
|
13
|
-
Array(
|
14
|
-
|
12
|
+
def legacy_subscribe(topics, options = {}, &block)
|
13
|
+
topics = Array(topics).map { |channel| "/topic/#{channel}" }
|
14
|
+
subscription(topics, options, &block)
|
15
|
+
end
|
16
|
+
alias subscribe legacy_subscribe
|
17
|
+
|
18
|
+
# Public: Subscribe to one or more Streaming API channels
|
19
|
+
#
|
20
|
+
# channels - The name of the Streaming API (cometD) channel(s) to subscribe to.
|
21
|
+
# block - A block to run when a new message is received.
|
22
|
+
#
|
23
|
+
# Returns a Faye::Subscription
|
24
|
+
def subscription(channels, options = {}, &block)
|
25
|
+
one_or_more_channels = Array(channels)
|
26
|
+
one_or_more_channels.each do |channel|
|
27
|
+
replay_handlers[channel] = options[:replay]
|
28
|
+
end
|
29
|
+
faye.subscribe(one_or_more_channels, &block)
|
15
30
|
end
|
16
31
|
|
17
32
|
# Public: Faye client to use for subscribing to PushTopics
|
@@ -49,7 +64,7 @@ module Restforce
|
|
49
64
|
|
50
65
|
def incoming(message, callback)
|
51
66
|
callback.call(message).tap do
|
52
|
-
channel = message.fetch('channel')
|
67
|
+
channel = message.fetch('channel')
|
53
68
|
replay_id = message.fetch('data', {}).fetch('event', {})['replayId']
|
54
69
|
|
55
70
|
handler = @replay_handlers[channel]
|
@@ -64,12 +79,12 @@ module Restforce
|
|
64
79
|
# Leave non-subscribe messages alone
|
65
80
|
return callback.call(message) unless message['channel'] == '/meta/subscribe'
|
66
81
|
|
67
|
-
channel = message['subscription']
|
82
|
+
channel = message['subscription']
|
68
83
|
|
69
84
|
# Set the replay value for the channel
|
70
85
|
message['ext'] ||= {}
|
71
86
|
message['ext']['replay'] = {
|
72
|
-
|
87
|
+
channel => replay_id(channel)
|
73
88
|
}
|
74
89
|
|
75
90
|
# Carry on and send the message to the server
|
data/lib/restforce/config.rb
CHANGED
@@ -108,6 +108,9 @@ module Restforce
|
|
108
108
|
# The OAuth client secret
|
109
109
|
option :client_secret, default: lambda { ENV['SALESFORCE_CLIENT_SECRET'] }
|
110
110
|
|
111
|
+
# The private key for JWT authentication
|
112
|
+
option :jwt_key
|
113
|
+
|
111
114
|
# Set this to true if you're authenticating with a Sandbox instance.
|
112
115
|
# Defaults to false.
|
113
116
|
option :host, default: lambda { ENV['SALESFORCE_HOST'] || 'login.salesforce.com' }
|
@@ -153,6 +156,9 @@ module Restforce
|
|
153
156
|
# Set a log level for logging when Restforce.log is set to true, defaulting to :debug
|
154
157
|
option :log_level, default: :debug
|
155
158
|
|
159
|
+
# Set use_cache to false to opt in to caching with client.with_caching
|
160
|
+
option :use_cache, default: true
|
161
|
+
|
156
162
|
def options
|
157
163
|
self.class.options
|
158
164
|
end
|
@@ -0,0 +1,406 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Restforce
|
4
|
+
module ErrorCode
|
5
|
+
GITHUB_ISSUE_URL = "https://github.com/restforce/restforce/issues/new?template=" \
|
6
|
+
"unhandled-salesforce-error.md&title=Unhandled+Salesforce+error%3A+%3Cinsert+" \
|
7
|
+
"error+code+here%3E"
|
8
|
+
|
9
|
+
# We define all of the known errors returned by Salesforce based on the
|
10
|
+
# documentation at
|
11
|
+
# https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_concepts_core_data_objects.htm#statuscode
|
12
|
+
# Previously, these were defined dynamically at runtime using `Module.const_set`. Now
|
13
|
+
# we define them up-front.
|
14
|
+
# It is possible that we will be missing some errors, so we will handle this in
|
15
|
+
# at least a semi-graceful manner.
|
16
|
+
class AllOrNoneOperationRolledBack < ResponseError; end
|
17
|
+
class AlreadyInProcess < ResponseError; end
|
18
|
+
class AssigneeTypeRequired < ResponseError; end
|
19
|
+
class BadCustomEntityParentDomain < ResponseError; end
|
20
|
+
class BccNotAllowedIfBccComplianceEnabled < ResponseError; end
|
21
|
+
class BccSelfNotAllowedIfBccComplianceEnabled < ResponseError; end
|
22
|
+
class CannotCascadeProductActive < ResponseError; end
|
23
|
+
class CannotChangeFieldTypeOfApexReferencedField < ResponseError; end
|
24
|
+
class CannotCreateAnotherManagedPackage < ResponseError; end
|
25
|
+
class CannotDeactivateDivision < ResponseError; end
|
26
|
+
class CannotDeleteLastDatedConversionRate < ResponseError; end
|
27
|
+
class CannotDeleteManagedObject < ResponseError; end
|
28
|
+
class CannotDisableLastAdmin < ResponseError; end
|
29
|
+
class CannotEnableIpRestrictRequests < ResponseError; end
|
30
|
+
class CannotInsertUpdateActivateEntity < ResponseError; end
|
31
|
+
class CannotModifyManagedObject < ResponseError; end
|
32
|
+
class CannotRenameApexReferencedField < ResponseError; end
|
33
|
+
class CannotRenameApexReferencedObject < ResponseError; end
|
34
|
+
class CannotReparentRecord < ResponseError; end
|
35
|
+
class CannotResolveName < ResponseError; end
|
36
|
+
class CannotUpdateConvertedLead < ResponseError; end
|
37
|
+
class CantDisableCorpCurrency < ResponseError; end
|
38
|
+
class CantUnsetCorpCurrency < ResponseError; end
|
39
|
+
class ChildShareFailsParent < ResponseError; end
|
40
|
+
class CircularDependency < ResponseError; end
|
41
|
+
class CommunityNotAccessible < ResponseError; end
|
42
|
+
class CustomClobFieldLimitExceeded < ResponseError; end
|
43
|
+
class CustomEntityOrFieldLimit < ResponseError; end
|
44
|
+
class CustomFieldIndexLimitExceeded < ResponseError; end
|
45
|
+
class CustomIndexExists < ResponseError; end
|
46
|
+
class CustomLinkLimitExceeded < ResponseError; end
|
47
|
+
class CustomMetadataLimitExceeded < ResponseError; end
|
48
|
+
class CustomSettingsLimitExceeded < ResponseError; end
|
49
|
+
class CustomTabLimitExceeded < ResponseError; end
|
50
|
+
class DeleteFailed < ResponseError; end
|
51
|
+
class DependencyExists < ResponseError; end
|
52
|
+
class DuplicateCaseSolution < ResponseError; end
|
53
|
+
class DuplicateCustomEntityDefinition < ResponseError; end
|
54
|
+
class DuplicateCustomTabMotif < ResponseError; end
|
55
|
+
class DuplicateDeveloperName < ResponseError; end
|
56
|
+
class DuplicatesDetected < ResponseError; end
|
57
|
+
class DuplicateExternalId < ResponseError; end
|
58
|
+
class DuplicateMasterLabel < ResponseError; end
|
59
|
+
class DuplicateSenderDisplayName < ResponseError; end
|
60
|
+
class DuplicateUsername < ResponseError; end
|
61
|
+
class DuplicateValue < ResponseError; end
|
62
|
+
class EmailAddressBounced < ResponseError; end
|
63
|
+
class EmailNotProcessedDueToPriorError < ResponseError; end
|
64
|
+
class EmailOptedOut < ResponseError; end
|
65
|
+
class EmailTemplateFormulaError < ResponseError; end
|
66
|
+
class EmailTemplateMergefieldAccessError < ResponseError; end
|
67
|
+
class EmailTemplateMergefieldError < ResponseError; end
|
68
|
+
class EmailTemplateMergefieldValueError < ResponseError; end
|
69
|
+
class EmailTemplateProcessingError < ResponseError; end
|
70
|
+
class EmptyScontrolFileName < ResponseError; end
|
71
|
+
class EntityFailedIflastmodifiedOnUpdate < ResponseError; end
|
72
|
+
class EntityIsArchived < ResponseError; end
|
73
|
+
class EntityIsDeleted < ResponseError; end
|
74
|
+
class EntityIsLocked < ResponseError; end
|
75
|
+
class EnvironmentHubMembershipConflict < ResponseError; end
|
76
|
+
class ErrorInMailer < ResponseError; end
|
77
|
+
class FailedActivation < ResponseError; end
|
78
|
+
class FieldCustomValidationException < ResponseError; end
|
79
|
+
class FieldFilterValidationException < ResponseError; end
|
80
|
+
class FilteredLookupLimitExceeded < ResponseError; end
|
81
|
+
class HtmlFileUploadNotAllowed < ResponseError; end
|
82
|
+
class ImageTooLarge < ResponseError; end
|
83
|
+
class InactiveOwnerOrUser < ResponseError; end
|
84
|
+
class InsertUpdateDeleteNotAllowedDuringMaintenance < ResponseError; end
|
85
|
+
class InsufficientAccessOnCrossReferenceEntity < ResponseError; end
|
86
|
+
class InsufficientAccessOrReadonly < ResponseError; end
|
87
|
+
class InvalidAccessLevel < ResponseError; end
|
88
|
+
class InvalidArgumentType < ResponseError; end
|
89
|
+
class InvalidAssigneeType < ResponseError; end
|
90
|
+
class InvalidAssignmentRule < ResponseError; end
|
91
|
+
class InvalidBatchOperation < ResponseError; end
|
92
|
+
class InvalidContentType < ResponseError; end
|
93
|
+
class InvalidCreditCardInfo < ResponseError; end
|
94
|
+
class InvalidCrossReferenceKey < ResponseError; end
|
95
|
+
class InvalidCrossReferenceTypeForField < ResponseError; end
|
96
|
+
class InvalidCurrencyConvRate < ResponseError; end
|
97
|
+
class InvalidCurrencyCorpRate < ResponseError; end
|
98
|
+
class InvalidCurrencyIso < ResponseError; end
|
99
|
+
class InvalidEmailAddress < ResponseError; end
|
100
|
+
class InvalidEmptyKeyOwner < ResponseError; end
|
101
|
+
class InvalidEventSubscription < ResponseError; end
|
102
|
+
class InvalidField < ResponseError; end
|
103
|
+
class InvalidFieldForInsertUpdate < ResponseError; end
|
104
|
+
class InvalidFieldWhenUsingTemplate < ResponseError; end
|
105
|
+
class InvalidFilterAction < ResponseError; end
|
106
|
+
class InvalidIdField < ResponseError; end
|
107
|
+
class InvalidInetAddress < ResponseError; end
|
108
|
+
class InvalidLineitemCloneState < ResponseError; end
|
109
|
+
class InvalidMasterOrTranslatedSolution < ResponseError; end
|
110
|
+
class InvalidMessageIdReference < ResponseError; end
|
111
|
+
class InvalidOperation < ResponseError; end
|
112
|
+
class InvalidOperator < ResponseError; end
|
113
|
+
class InvalidOrNullForRestrictedPicklist < ResponseError; end
|
114
|
+
class InvalidPartnerNetworkStatus < ResponseError; end
|
115
|
+
class InvalidPersonAccountOperation < ResponseError; end
|
116
|
+
class InvalidReadOnlyUserDml < ResponseError; end
|
117
|
+
class InvalidSaveAsActivityFlag < ResponseError; end
|
118
|
+
class InvalidSessionId < ResponseError; end
|
119
|
+
class InvalidStatus < ResponseError; end
|
120
|
+
class InvalidType < ResponseError; end
|
121
|
+
class InvalidTypeForOperation < ResponseError; end
|
122
|
+
class InvalidTypeOnFieldInRecord < ResponseError; end
|
123
|
+
class IpRangeLimitExceeded < ResponseError; end
|
124
|
+
class JigsawImportLimitExceeded < ResponseError; end
|
125
|
+
class LicenseLimitExceeded < ResponseError; end
|
126
|
+
class LightPortalUserException < ResponseError; end
|
127
|
+
class LimitExceeded < ResponseError; end
|
128
|
+
class LoginChallengeIssued < ResponseError; end
|
129
|
+
class LoginChallengePending < ResponseError; end
|
130
|
+
class LoginMustUseSecurityToken < ResponseError; end
|
131
|
+
class MalformedId < ResponseError; end
|
132
|
+
class ManagerNotDefined < ResponseError; end
|
133
|
+
class MassmailRetryLimitExceeded < ResponseError; end
|
134
|
+
class MassMailLimitExceeded < ResponseError; end
|
135
|
+
class MaximumCcemailsExceeded < ResponseError; end
|
136
|
+
class MaximumDashboardComponentsExceeded < ResponseError; end
|
137
|
+
class MaximumHierarchyLevelsReached < ResponseError; end
|
138
|
+
class MaximumSizeOfAttachment < ResponseError; end
|
139
|
+
class MaximumSizeOfDocument < ResponseError; end
|
140
|
+
class MaxActionsPerRuleExceeded < ResponseError; end
|
141
|
+
class MaxActiveRulesExceeded < ResponseError; end
|
142
|
+
class MaxApprovalStepsExceeded < ResponseError; end
|
143
|
+
class MaxFormulasPerRuleExceeded < ResponseError; end
|
144
|
+
class MaxRulesExceeded < ResponseError; end
|
145
|
+
class MaxRuleEntriesExceeded < ResponseError; end
|
146
|
+
class MaxTaskDescriptionExceeded < ResponseError; end
|
147
|
+
class MaxTmRulesExceeded < ResponseError; end
|
148
|
+
class MaxTmRuleItemsExceeded < ResponseError; end
|
149
|
+
class MergeFailed < ResponseError; end
|
150
|
+
class MissingArgument < ResponseError; end
|
151
|
+
class NonuniqueShippingAddress < ResponseError; end
|
152
|
+
class NoApplicableProcess < ResponseError; end
|
153
|
+
class NoAttachmentPermission < ResponseError; end
|
154
|
+
class NoInactiveDivisionMembers < ResponseError; end
|
155
|
+
class NoMassMailPermission < ResponseError; end
|
156
|
+
class NumberOutsideValidRange < ResponseError; end
|
157
|
+
class NumHistoryFieldsBySobjectExceeded < ResponseError; end
|
158
|
+
class OpWithInvalidUserTypeException < ResponseError; end
|
159
|
+
class OptedOutOfMassMail < ResponseError; end
|
160
|
+
class PackageLicenseRequired < ResponseError; end
|
161
|
+
class PlatformEventEncryptionError < ResponseError; end
|
162
|
+
class PlatformEventPublishingUnavailable < ResponseError; end
|
163
|
+
class PlatformEventPublishFailed < ResponseError; end
|
164
|
+
class PortalUserAlreadyExistsForContact < ResponseError; end
|
165
|
+
class PrivateContactOnAsset < ResponseError; end
|
166
|
+
class RecordInUseByWorkflow < ResponseError; end
|
167
|
+
class RequestRunningTooLong < ResponseError; end
|
168
|
+
class RequiredFieldMissing < ResponseError; end
|
169
|
+
class SelfReferenceFromTrigger < ResponseError; end
|
170
|
+
class ShareNeededForChildOwner < ResponseError; end
|
171
|
+
class SingleEmailLimitExceeded < ResponseError; end
|
172
|
+
class StandardPriceNotDefined < ResponseError; end
|
173
|
+
class StorageLimitExceeded < ResponseError; end
|
174
|
+
class StringTooLong < ResponseError; end
|
175
|
+
class TabsetLimitExceeded < ResponseError; end
|
176
|
+
class TemplateNotActive < ResponseError; end
|
177
|
+
class TerritoryRealignInProgress < ResponseError; end
|
178
|
+
class TextDataOutsideSupportedCharset < ResponseError; end
|
179
|
+
class TooManyApexRequests < ResponseError; end
|
180
|
+
class TooManyEnumValue < ResponseError; end
|
181
|
+
class TransferRequiresRead < ResponseError; end
|
182
|
+
class UnableToLockRow < ResponseError; end
|
183
|
+
class UnavailableRecordtypeException < ResponseError; end
|
184
|
+
class UndeleteFailed < ResponseError; end
|
185
|
+
class UnknownException < ResponseError; end
|
186
|
+
class UnspecifiedEmailAddress < ResponseError; end
|
187
|
+
class UnsupportedApexTriggerOperation < ResponseError; end
|
188
|
+
class UnverifiedSenderAddress < ResponseError; end
|
189
|
+
class WeblinkSizeLimitExceeded < ResponseError; end
|
190
|
+
class WeblinkUrlInvalid < ResponseError; end
|
191
|
+
class WrongControllerType < ResponseError; end
|
192
|
+
|
193
|
+
# Maps `errorCode`s returned from Salesforce to the exception class
|
194
|
+
# to be used for these errors
|
195
|
+
ERROR_EXCEPTION_CLASSES = {
|
196
|
+
"ALL_OR_NONE_OPERATION_ROLLED_BACK" => AllOrNoneOperationRolledBack,
|
197
|
+
"ALREADY_IN_PROCESS" => AlreadyInProcess,
|
198
|
+
"ASSIGNEE_TYPE_REQUIRED" => AssigneeTypeRequired,
|
199
|
+
"BAD_CUSTOM_ENTITY_PARENT_DOMAIN" => BadCustomEntityParentDomain,
|
200
|
+
"BCC_NOT_ALLOWED_IF_BCC_COMPLIANCE_ENABLED" =>
|
201
|
+
BccNotAllowedIfBccComplianceEnabled,
|
202
|
+
"BCC_SELF_NOT_ALLOWED_IF_BCC_COMPLIANCE_ENABLED" =>
|
203
|
+
BccSelfNotAllowedIfBccComplianceEnabled,
|
204
|
+
"CANNOT_CASCADE_PRODUCT_ACTIVE" => CannotCascadeProductActive,
|
205
|
+
"CANNOT_CHANGE_FIELD_TYPE_OF_APEX_REFERENCED_FIELD" =>
|
206
|
+
CannotChangeFieldTypeOfApexReferencedField,
|
207
|
+
"CANNOT_CREATE_ANOTHER_MANAGED_PACKAGE" => CannotCreateAnotherManagedPackage,
|
208
|
+
"CANNOT_DEACTIVATE_DIVISION" => CannotDeactivateDivision,
|
209
|
+
"CANNOT_DELETE_LAST_DATED_CONVERSION_RATE" =>
|
210
|
+
CannotDeleteLastDatedConversionRate,
|
211
|
+
"CANNOT_DELETE_MANAGED_OBJECT" => CannotDeleteManagedObject,
|
212
|
+
"CANNOT_DISABLE_LAST_ADMIN" => CannotDisableLastAdmin,
|
213
|
+
"CANNOT_ENABLE_IP_RESTRICT_REQUESTS" => CannotEnableIpRestrictRequests,
|
214
|
+
"CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY" => CannotInsertUpdateActivateEntity,
|
215
|
+
"CANNOT_MODIFY_MANAGED_OBJECT" => CannotModifyManagedObject,
|
216
|
+
"CANNOT_RENAME_APEX_REFERENCED_FIELD" => CannotRenameApexReferencedField,
|
217
|
+
"CANNOT_RENAME_APEX_REFERENCED_OBJECT" => CannotRenameApexReferencedObject,
|
218
|
+
"CANNOT_REPARENT_RECORD" => CannotReparentRecord,
|
219
|
+
"CANNOT_RESOLVE_NAME" => CannotResolveName,
|
220
|
+
"CANNOT_UPDATE_CONVERTED_LEAD" => CannotUpdateConvertedLead,
|
221
|
+
"CANT_DISABLE_CORP_CURRENCY" => CantDisableCorpCurrency,
|
222
|
+
"CANT_UNSET_CORP_CURRENCY" => CantUnsetCorpCurrency,
|
223
|
+
"CHILD_SHARE_FAILS_PARENT" => ChildShareFailsParent,
|
224
|
+
"CIRCULAR_DEPENDENCY" => CircularDependency,
|
225
|
+
"COMMUNITY_NOT_ACCESSIBLE" => CommunityNotAccessible,
|
226
|
+
"CUSTOM_CLOB_FIELD_LIMIT_EXCEEDED" => CustomClobFieldLimitExceeded,
|
227
|
+
"CUSTOM_ENTITY_OR_FIELD_LIMIT" => CustomEntityOrFieldLimit,
|
228
|
+
"CUSTOM_FIELD_INDEX_LIMIT_EXCEEDED" => CustomFieldIndexLimitExceeded,
|
229
|
+
"CUSTOM_INDEX_EXISTS" => CustomIndexExists,
|
230
|
+
"CUSTOM_LINK_LIMIT_EXCEEDED" => CustomLinkLimitExceeded,
|
231
|
+
"CUSTOM_METADATA_LIMIT_EXCEEDED" => CustomMetadataLimitExceeded,
|
232
|
+
"CUSTOM_SETTINGS_LIMIT_EXCEEDED" => CustomSettingsLimitExceeded,
|
233
|
+
"CUSTOM_TAB_LIMIT_EXCEEDED" => CustomTabLimitExceeded,
|
234
|
+
"DELETE_FAILED" => DeleteFailed,
|
235
|
+
"DEPENDENCY_EXISTS" => DependencyExists,
|
236
|
+
"DUPLICATE_CASE_SOLUTION" => DuplicateCaseSolution,
|
237
|
+
"DUPLICATE_CUSTOM_ENTITY_DEFINITION" => DuplicateCustomEntityDefinition,
|
238
|
+
"DUPLICATE_CUSTOM_TAB_MOTIF" => DuplicateCustomTabMotif,
|
239
|
+
"DUPLICATE_DEVELOPER_NAME" => DuplicateDeveloperName,
|
240
|
+
"DUPLICATES_DETECTED" => DuplicatesDetected,
|
241
|
+
"DUPLICATE_EXTERNAL_ID" => DuplicateExternalId,
|
242
|
+
"DUPLICATE_MASTER_LABEL" => DuplicateMasterLabel,
|
243
|
+
"DUPLICATE_SENDER_DISPLAY_NAME" => DuplicateSenderDisplayName,
|
244
|
+
"DUPLICATE_USERNAME" => DuplicateUsername,
|
245
|
+
"DUPLICATE_VALUE" => DuplicateValue,
|
246
|
+
"EMAIL_ADDRESS_BOUNCED" => EmailAddressBounced,
|
247
|
+
"EMAIL_NOT_PROCESSED_DUE_TO_PRIOR_ERROR" => EmailNotProcessedDueToPriorError,
|
248
|
+
"EMAIL_OPTED_OUT" => EmailOptedOut,
|
249
|
+
"EMAIL_TEMPLATE_FORMULA_ERROR" => EmailTemplateFormulaError,
|
250
|
+
"EMAIL_TEMPLATE_MERGEFIELD_ACCESS_ERROR" =>
|
251
|
+
EmailTemplateMergefieldAccessError,
|
252
|
+
"EMAIL_TEMPLATE_MERGEFIELD_ERROR" => EmailTemplateMergefieldError,
|
253
|
+
"EMAIL_TEMPLATE_MERGEFIELD_VALUE_ERROR" => EmailTemplateMergefieldValueError,
|
254
|
+
"EMAIL_TEMPLATE_PROCESSING_ERROR" => EmailTemplateProcessingError,
|
255
|
+
"EMPTY_SCONTROL_FILE_NAME" => EmptyScontrolFileName,
|
256
|
+
"ENTITY_FAILED_IFLASTMODIFIED_ON_UPDATE" =>
|
257
|
+
EntityFailedIflastmodifiedOnUpdate,
|
258
|
+
"ENTITY_IS_ARCHIVED" => EntityIsArchived,
|
259
|
+
"ENTITY_IS_DELETED" => EntityIsDeleted,
|
260
|
+
"ENTITY_IS_LOCKED" => EntityIsLocked,
|
261
|
+
"ENVIRONMENT_HUB_MEMBERSHIP_CONFLICT" => EnvironmentHubMembershipConflict,
|
262
|
+
"ERROR_IN_MAILER" => ErrorInMailer,
|
263
|
+
"FAILED_ACTIVATION" => FailedActivation,
|
264
|
+
"FIELD_CUSTOM_VALIDATION_EXCEPTION" => FieldCustomValidationException,
|
265
|
+
"FIELD_FILTER_VALIDATION_EXCEPTION" => FieldFilterValidationException,
|
266
|
+
"FILTERED_LOOKUP_LIMIT_EXCEEDED" => FilteredLookupLimitExceeded,
|
267
|
+
"HTML_FILE_UPLOAD_NOT_ALLOWED" => HtmlFileUploadNotAllowed,
|
268
|
+
"IMAGE_TOO_LARGE" => ImageTooLarge,
|
269
|
+
"INACTIVE_OWNER_OR_USER" => InactiveOwnerOrUser,
|
270
|
+
"INSERT_UPDATE_DELETE_NOT_ALLOWED_DURING_MAINTENANCE" =>
|
271
|
+
InsertUpdateDeleteNotAllowedDuringMaintenance,
|
272
|
+
"INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY" =>
|
273
|
+
InsufficientAccessOnCrossReferenceEntity,
|
274
|
+
"INSUFFICIENT_ACCESS_OR_READONLY" => InsufficientAccessOrReadonly,
|
275
|
+
"INVALID_ACCESS_LEVEL" => InvalidAccessLevel,
|
276
|
+
"INVALID_ARGUMENT_TYPE" => InvalidArgumentType,
|
277
|
+
"INVALID_ASSIGNEE_TYPE" => InvalidAssigneeType,
|
278
|
+
"INVALID_ASSIGNMENT_RULE" => InvalidAssignmentRule,
|
279
|
+
"INVALID_BATCH_OPERATION" => InvalidBatchOperation,
|
280
|
+
"INVALID_CONTENT_TYPE" => InvalidContentType,
|
281
|
+
"INVALID_CREDIT_CARD_INFO" => InvalidCreditCardInfo,
|
282
|
+
"INVALID_CROSS_REFERENCE_KEY" => InvalidCrossReferenceKey,
|
283
|
+
"INVALID_CROSS_REFERENCE_TYPE_FOR_FIELD" => InvalidCrossReferenceTypeForField,
|
284
|
+
"INVALID_CURRENCY_CONV_RATE" => InvalidCurrencyConvRate,
|
285
|
+
"INVALID_CURRENCY_CORP_RATE" => InvalidCurrencyCorpRate,
|
286
|
+
"INVALID_CURRENCY_ISO" => InvalidCurrencyIso,
|
287
|
+
"INVALID_EMAIL_ADDRESS" => InvalidEmailAddress,
|
288
|
+
"INVALID_EMPTY_KEY_OWNER" => InvalidEmptyKeyOwner,
|
289
|
+
"INVALID_EVENT_SUBSCRIPTION" => InvalidEventSubscription,
|
290
|
+
"INVALID_FIELD" => InvalidField,
|
291
|
+
"INVALID_FIELD_FOR_INSERT_UPDATE" => InvalidFieldForInsertUpdate,
|
292
|
+
"INVALID_FIELD_WHEN_USING_TEMPLATE" => InvalidFieldWhenUsingTemplate,
|
293
|
+
"INVALID_FILTER_ACTION" => InvalidFilterAction,
|
294
|
+
"INVALID_ID_FIELD" => InvalidIdField,
|
295
|
+
"INVALID_INET_ADDRESS" => InvalidInetAddress,
|
296
|
+
"INVALID_LINEITEM_CLONE_STATE" => InvalidLineitemCloneState,
|
297
|
+
"INVALID_MASTER_OR_TRANSLATED_SOLUTION" => InvalidMasterOrTranslatedSolution,
|
298
|
+
"INVALID_MESSAGE_ID_REFERENCE" => InvalidMessageIdReference,
|
299
|
+
"INVALID_OPERATION" => InvalidOperation,
|
300
|
+
"INVALID_OPERATOR" => InvalidOperator,
|
301
|
+
"INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST" =>
|
302
|
+
InvalidOrNullForRestrictedPicklist,
|
303
|
+
"INVALID_PARTNER_NETWORK_STATUS" => InvalidPartnerNetworkStatus,
|
304
|
+
"INVALID_PERSON_ACCOUNT_OPERATION" => InvalidPersonAccountOperation,
|
305
|
+
"INVALID_READ_ONLY_USER_DML" => InvalidReadOnlyUserDml,
|
306
|
+
"INVALID_SAVE_AS_ACTIVITY_FLAG" => InvalidSaveAsActivityFlag,
|
307
|
+
"INVALID_SESSION_ID" => InvalidSessionId,
|
308
|
+
"INVALID_STATUS" => InvalidStatus,
|
309
|
+
"INVALID_TYPE" => InvalidType,
|
310
|
+
"INVALID_TYPE_FOR_OPERATION" => InvalidTypeForOperation,
|
311
|
+
"INVALID_TYPE_ON_FIELD_IN_RECORD" => InvalidTypeOnFieldInRecord,
|
312
|
+
"IP_RANGE_LIMIT_EXCEEDED" => IpRangeLimitExceeded,
|
313
|
+
"JIGSAW_IMPORT_LIMIT_EXCEEDED" => JigsawImportLimitExceeded,
|
314
|
+
"LICENSE_LIMIT_EXCEEDED" => LicenseLimitExceeded,
|
315
|
+
"LIGHT_PORTAL_USER_EXCEPTION" => LightPortalUserException,
|
316
|
+
"LIMIT_EXCEEDED" => LimitExceeded,
|
317
|
+
"LOGIN_CHALLENGE_ISSUED" => LoginChallengeIssued,
|
318
|
+
"LOGIN_CHALLENGE_PENDING" => LoginChallengePending,
|
319
|
+
"LOGIN_MUST_USE_SECURITY_TOKEN" => LoginMustUseSecurityToken,
|
320
|
+
"MALFORMED_ID" => MalformedId,
|
321
|
+
"MANAGER_NOT_DEFINED" => ManagerNotDefined,
|
322
|
+
"MASSMAIL_RETRY_LIMIT_EXCEEDED" => MassmailRetryLimitExceeded,
|
323
|
+
"MASS_MAIL_LIMIT_EXCEEDED" => MassMailLimitExceeded,
|
324
|
+
"MAXIMUM_CCEMAILS_EXCEEDED" => MaximumCcemailsExceeded,
|
325
|
+
"MAXIMUM_DASHBOARD_COMPONENTS_EXCEEDED" => MaximumDashboardComponentsExceeded,
|
326
|
+
"MAXIMUM_HIERARCHY_LEVELS_REACHED" => MaximumHierarchyLevelsReached,
|
327
|
+
"MAXIMUM_SIZE_OF_ATTACHMENT" => MaximumSizeOfAttachment,
|
328
|
+
"MAXIMUM_SIZE_OF_DOCUMENT" => MaximumSizeOfDocument,
|
329
|
+
"MAX_ACTIONS_PER_RULE_EXCEEDED" => MaxActionsPerRuleExceeded,
|
330
|
+
"MAX_ACTIVE_RULES_EXCEEDED" => MaxActiveRulesExceeded,
|
331
|
+
"MAX_APPROVAL_STEPS_EXCEEDED" => MaxApprovalStepsExceeded,
|
332
|
+
"MAX_FORMULAS_PER_RULE_EXCEEDED" => MaxFormulasPerRuleExceeded,
|
333
|
+
"MAX_RULES_EXCEEDED" => MaxRulesExceeded,
|
334
|
+
"MAX_RULE_ENTRIES_EXCEEDED" => MaxRuleEntriesExceeded,
|
335
|
+
"MAX_TASK_DESCRIPTION_EXCEEDED" => MaxTaskDescriptionExceeded,
|
336
|
+
"MAX_TM_RULES_EXCEEDED" => MaxTmRulesExceeded,
|
337
|
+
"MAX_TM_RULE_ITEMS_EXCEEDED" => MaxTmRuleItemsExceeded,
|
338
|
+
"MERGE_FAILED" => MergeFailed,
|
339
|
+
"MISSING_ARGUMENT" => MissingArgument,
|
340
|
+
"NONUNIQUE_SHIPPING_ADDRESS" => NonuniqueShippingAddress,
|
341
|
+
"NO_APPLICABLE_PROCESS" => NoApplicableProcess,
|
342
|
+
"NO_ATTACHMENT_PERMISSION" => NoAttachmentPermission,
|
343
|
+
"NO_INACTIVE_DIVISION_MEMBERS" => NoInactiveDivisionMembers,
|
344
|
+
"NO_MASS_MAIL_PERMISSION" => NoMassMailPermission,
|
345
|
+
"NUMBER_OUTSIDE_VALID_RANGE" => NumberOutsideValidRange,
|
346
|
+
"NUM_HISTORY_FIELDS_BY_SOBJECT_EXCEEDED" => NumHistoryFieldsBySobjectExceeded,
|
347
|
+
"OP_WITH_INVALID_USER_TYPE_EXCEPTION" => OpWithInvalidUserTypeException,
|
348
|
+
"OPTED_OUT_OF_MASS_MAIL" => OptedOutOfMassMail,
|
349
|
+
"PACKAGE_LICENSE_REQUIRED" => PackageLicenseRequired,
|
350
|
+
"PLATFORM_EVENT_ENCRYPTION_ERROR" => PlatformEventEncryptionError,
|
351
|
+
"PLATFORM_EVENT_PUBLISHING_UNAVAILABLE" => PlatformEventPublishingUnavailable,
|
352
|
+
"PLATFORM_EVENT_PUBLISH_FAILED" => PlatformEventPublishFailed,
|
353
|
+
"PORTAL_USER_ALREADY_EXISTS_FOR_CONTACT" => PortalUserAlreadyExistsForContact,
|
354
|
+
"PRIVATE_CONTACT_ON_ASSET" => PrivateContactOnAsset,
|
355
|
+
"RECORD_IN_USE_BY_WORKFLOW" => RecordInUseByWorkflow,
|
356
|
+
"REQUEST_RUNNING_TOO_LONG" => RequestRunningTooLong,
|
357
|
+
"REQUIRED_FIELD_MISSING" => RequiredFieldMissing,
|
358
|
+
"SELF_REFERENCE_FROM_TRIGGER" => SelfReferenceFromTrigger,
|
359
|
+
"SHARE_NEEDED_FOR_CHILD_OWNER" => ShareNeededForChildOwner,
|
360
|
+
"SINGLE_EMAIL_LIMIT_EXCEEDED" => SingleEmailLimitExceeded,
|
361
|
+
"STANDARD_PRICE_NOT_DEFINED" => StandardPriceNotDefined,
|
362
|
+
"STORAGE_LIMIT_EXCEEDED" => StorageLimitExceeded,
|
363
|
+
"STRING_TOO_LONG" => StringTooLong,
|
364
|
+
"TABSET_LIMIT_EXCEEDED" => TabsetLimitExceeded,
|
365
|
+
"TEMPLATE_NOT_ACTIVE" => TemplateNotActive,
|
366
|
+
"TERRITORY_REALIGN_IN_PROGRESS" => TerritoryRealignInProgress,
|
367
|
+
"TEXT_DATA_OUTSIDE_SUPPORTED_CHARSET" => TextDataOutsideSupportedCharset,
|
368
|
+
"TOO_MANY_APEX_REQUESTS" => TooManyApexRequests,
|
369
|
+
"TOO_MANY_ENUM_VALUE" => TooManyEnumValue,
|
370
|
+
"TRANSFER_REQUIRES_READ" => TransferRequiresRead,
|
371
|
+
"UNABLE_TO_LOCK_ROW" => UnableToLockRow,
|
372
|
+
"UNAVAILABLE_RECORDTYPE_EXCEPTION" => UnavailableRecordtypeException,
|
373
|
+
"UNDELETE_FAILED" => UndeleteFailed,
|
374
|
+
"UNKNOWN_EXCEPTION" => UnknownException,
|
375
|
+
"UNSPECIFIED_EMAIL_ADDRESS" => UnspecifiedEmailAddress,
|
376
|
+
"UNSUPPORTED_APEX_TRIGGER_OPERATION" => UnsupportedApexTriggerOperation,
|
377
|
+
"UNVERIFIED_SENDER_ADDRESS" => UnverifiedSenderAddress,
|
378
|
+
"WEBLINK_SIZE_LIMIT_EXCEEDED" => WeblinkSizeLimitExceeded,
|
379
|
+
"WEBLINK_URL_INVALID" => WeblinkUrlInvalid,
|
380
|
+
"WRONG_CONTROLLER_TYPE" => WrongControllerType
|
381
|
+
}.freeze
|
382
|
+
|
383
|
+
def self.get_exception_class(error_code)
|
384
|
+
ERROR_EXCEPTION_CLASSES.fetch(error_code) do |_|
|
385
|
+
warn "[restforce] An unrecognised error code, `#{error_code}` has been " \
|
386
|
+
"received from Salesforce. Instead of raising an error-specific exception, " \
|
387
|
+
"we'll raise a generic `ResponseError`. Please report this missing error code" \
|
388
|
+
" on GitHub at <#{GITHUB_ISSUE_URL}>."
|
389
|
+
|
390
|
+
# If we've received an unexpected error where we don't have a specific
|
391
|
+
# class defined, we can return a generic ResponseError instead
|
392
|
+
ResponseError
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def self.const_missing(constant_name)
|
397
|
+
warn "[restforce] You're referring to a Restforce error that isn't defined, " \
|
398
|
+
"`#{name}::#{constant_name}` (for example by trying to `rescue` it). This might " \
|
399
|
+
"be our fault - we've recently made some changes to how errors are defined. If " \
|
400
|
+
"you're sure that this is a valid Salesforce error, then please create an " \
|
401
|
+
"issue on GitHub at <#{GITHUB_ISSUE_URL}>."
|
402
|
+
|
403
|
+
super(constant_name)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|