Error during processing error message

KB2446498 — FIX: «An error occurred during local report processing» error message may occur when you export a report in SQL Server 2008 Reporting Services Microsoft distributes Microsoft SQL Server 2008 fixes as one downloadable file. Because the fixes are cumulative, each new release contains all the hotfixes and all the security fixes that […]

Содержание

  1. KB2446498 — FIX: «An error occurred during local report processing» error message may occur when you export a report in SQL Server 2008 Reporting Services
  2. Symptoms
  3. Resolution
  4. Cumulative update information
  5. SQL Server 2008
  6. SQL Server 2008 Service Pack 2
  7. Status
  8. References
  9. KB2446498 — FIX: «An error occurred during local report processing» error message may occur when you export a report in SQL Server 2008 Reporting Services
  10. Symptoms
  11. Resolution
  12. Cumulative update information
  13. SQL Server 2008
  14. SQL Server 2008 Service Pack 2
  15. Status
  16. References
  17. Error during processing error message
  18. Answered by:
  19. Question
  20. Answers
  21. Error during processing error message
  22. Overview of Oracle GoldenGate Error Handling
  23. Handling Extract Errors
  24. Handling Replicat Errors during DML Operations
  25. Handling Errors as Exceptions

KB2446498 — FIX: «An error occurred during local report processing» error message may occur when you export a report in SQL Server 2008 Reporting Services

Microsoft distributes Microsoft SQL Server 2008 fixes as one downloadable file. Because the fixes are cumulative, each new release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release.

Symptoms

Consider the following scenario:

You create a report in Microsoft SQL Server 2008 Reporting Services (SSRS 2008).

You define a Tablix control and an expression in the header or footer of the report.

You define a parent group and a child group in the Tablix control.

You try to export the report to a file that is a hard page-break renderer . For example, you try to export the report to a PDF-formatted or TIFF-formatted file. The parent group is not expanded before you export the report.

In this scenario, you may receive the following error message:

An error occurred during local report processing.
An internal error occurred on the report server. See the error log for more details.

Resolution

Cumulative update information

SQL Server 2008

The fix for this issue was first released in Cumulative Update 11 for SQL Server 2008 Service Pack 1.

For more information about this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2413738 Cumulative update package 11 for SQL Server 2008 Service Pack 1Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release. Microsoft recommends that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

970365 The SQL Server 2008 builds that were released after SQL Server 2008 Service Pack 1 was released Microsoft SQL Server 2008 hotfixes are created for specific SQL Server service packs. You must apply a SQL Server 2008 Service Pack 1 hotfix to an installation of SQL Server 2008 Service Pack 1. By default, any hotfix that is provided in a SQL Server service pack is included in the next SQL Server service pack.

SQL Server 2008 Service Pack 2

The fix for this issue was first released in Cumulative Update 2 for SQL Server 2008 Service Pack 2. For more information about this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2467239 Cumulative update package 2 for SQL Server 2008 Service Pack 2Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release. Microsoft recommends that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2402659 The SQL Server 2008 builds that were released after SQL Server 2008 Service Pack 2 was released Microsoft SQL Server 2008 hotfixes are created for specific SQL Server service packs. You must apply a SQL Server 2008 Service Pack 2 hotfix to an installation of SQL Server 2008 Service Pack 2. By default, any hotfix that is provided in a SQL Server service pack is included in the next SQL Server service pack.

Status

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the «Applies to» section.

References

For more information about the Incremental Servicing Model for SQL Server, click the following article number to view the article in the Microsoft Knowledge Base:

935897 An Incremental Servicing Model is available from the SQL Server team to deliver hotfixes for reported problems

For more information about the naming schema for SQL Server updates, click the following article number to view the article in the Microsoft Knowledge Base:

822499New naming schema for Microsoft SQL Server software update packagesFor more information about software update terminology, click the following article number to view the article in the Microsoft Knowledge Base:

824684 Description of the standard terminology that is used to describe Microsoft software updates

Источник

KB2446498 — FIX: «An error occurred during local report processing» error message may occur when you export a report in SQL Server 2008 Reporting Services

Microsoft distributes Microsoft SQL Server 2008 fixes as one downloadable file. Because the fixes are cumulative, each new release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release.

Symptoms

Consider the following scenario:

You create a report in Microsoft SQL Server 2008 Reporting Services (SSRS 2008).

You define a Tablix control and an expression in the header or footer of the report.

You define a parent group and a child group in the Tablix control.

You try to export the report to a file that is a hard page-break renderer . For example, you try to export the report to a PDF-formatted or TIFF-formatted file. The parent group is not expanded before you export the report.

In this scenario, you may receive the following error message:

An error occurred during local report processing.
An internal error occurred on the report server. See the error log for more details.

Resolution

Cumulative update information

SQL Server 2008

The fix for this issue was first released in Cumulative Update 11 for SQL Server 2008 Service Pack 1.

For more information about this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2413738 Cumulative update package 11 for SQL Server 2008 Service Pack 1Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release. Microsoft recommends that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

970365 The SQL Server 2008 builds that were released after SQL Server 2008 Service Pack 1 was released Microsoft SQL Server 2008 hotfixes are created for specific SQL Server service packs. You must apply a SQL Server 2008 Service Pack 1 hotfix to an installation of SQL Server 2008 Service Pack 1. By default, any hotfix that is provided in a SQL Server service pack is included in the next SQL Server service pack.

SQL Server 2008 Service Pack 2

The fix for this issue was first released in Cumulative Update 2 for SQL Server 2008 Service Pack 2. For more information about this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2467239 Cumulative update package 2 for SQL Server 2008 Service Pack 2Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 fix release. Microsoft recommends that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2402659 The SQL Server 2008 builds that were released after SQL Server 2008 Service Pack 2 was released Microsoft SQL Server 2008 hotfixes are created for specific SQL Server service packs. You must apply a SQL Server 2008 Service Pack 2 hotfix to an installation of SQL Server 2008 Service Pack 2. By default, any hotfix that is provided in a SQL Server service pack is included in the next SQL Server service pack.

Status

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the «Applies to» section.

References

For more information about the Incremental Servicing Model for SQL Server, click the following article number to view the article in the Microsoft Knowledge Base:

935897 An Incremental Servicing Model is available from the SQL Server team to deliver hotfixes for reported problems

For more information about the naming schema for SQL Server updates, click the following article number to view the article in the Microsoft Knowledge Base:

822499New naming schema for Microsoft SQL Server software update packagesFor more information about software update terminology, click the following article number to view the article in the Microsoft Knowledge Base:

824684 Description of the standard terminology that is used to describe Microsoft software updates

Источник

Error during processing error message

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

An error has occurred during report processing.

  • Cannot set the command text for data set ‘ScoreboardOLAP’.
    • Error during processing of the CommandText expression of dataset ‘ScoreboardOLAP’

Can anyone help at all here? I’ve seen about 10 articles on this one but none appear to be relevant. I have a complex report comprising many sub-reports which runs successfully in a development environment. When deployed to an environment which comprises a separate report sever and report server DB I get the above error even when I try and browse to any of the sub-reports.

The sub-report is using an OLEDB connection to an SSAS DB and its command text is set as:-

Where GetQueryString is a function in the code section of the report which returns some MDX based on the supplied parameters. I obviously know the function works because it works in development mode.

I have tried to determine what is going on from the logs but the only messages I get are those above. I’ve set the data sources on the server up to use valid Windows Credentials stored on the server so I don’t believe the issue is one of authentication

Any thoughts or tips in helping to diagnose the cause of the problem would be greatly appreciated.

Answers

Solved — and I’ve seen a number of other users with this issue so pay attention.

The problem is one of security. The default security policy for ReportServer is NOT to allow code to be executed. Therefore any references to Code. within a report will not run in a default deployment environment. This makes perfect sense if you think that users can create and publish their own reports onto report server and by using Code blocks, could easily write managed code to publish present information relating to the run-time environment on which the report is running.

However, and this is my rant. — why oh why oh why do people blindly follow OOD articles by respected industry thinkers relating to the management of exceptions. I’ve seen so many articles talking about catching exceptions within the various layers of an application, wrapping them and then passing them up the exception chain. This is exactly what seems to be happening with this problem i.e. the Code block cannot be executed — therefore throw an exception. Unfortunately what then happens is that the various layers above catch this exception, wrap it up again and throw it on until at the top layer you end up with some non-sensical exception message such as

‘ Cannot set the command text for data set’

Even with by examining the SSRS report server logs, you cannot see the inner exceptions and therefore cannot work out what is really going on.

I compare this to Chinese whispers where at the top layer you end up with something totally non-sensical and unrelated to the error that actually occurred. If you have to bubble up exceptions, at least make the exception stack visible. Personally I believe that exceptions should only be caught when it makes sense to do so (i.e. there is some bespoke action to be taken based on the exception type), otherwise you end up spending signifcant amounts of time trying to work out what actually is going wrong.

This is not the first time I’ve seen exceptions within .NET products not bubbling up correctly and leading to incorrect error presentation at the top layer.

Of course this is my personal opinion but I’ve been doing this sort of stuff for 25 years now and would like to think I’ve learnt a thing or two by now.

Источник

Error during processing error message

Oracle GoldenGate reports processing errors in several ways by means of its monitoring and reporting tools. For more information about these tools, see Monitoring Oracle GoldenGate Processing.

Overview of Oracle GoldenGate Error Handling

Oracle GoldenGate provides error-handling options for:

Handling Extract Errors

There is no specific parameter to handle Extract errors when DML operations are being extracted, but Extract does provide a number of parameters that can be used to prevent anticipated problems. These parameters handle anomalies that can occur during the processing of DML operations, such as what to do when a row to be fetched cannot be located, or what to do when the transaction log is not available. The following is a partial list of these parameters.

To handle extraction errors that relate to DDL operations, use the DDLERROR parameter.

For a complete parameter list, see Reference for Oracle GoldenGate .

Handling Replicat Errors during DML Operations

To control the way that Replicat responds to an error during one of its DML statements, use the REPERROR parameter in the Replicat parameter file. You can use REPERROR as a global parameter or as part of a MAP statement. You can handle most errors in a default fashion (for example, to cease processing) with DEFAULT and DEFAULT2 options, and also handle other errors in a specific manner.

The following comprise the range of REPERROR responses:

ABEND : roll back the transaction and stop processing.

DISCARD : log the error to the discard file and continue processing.

EXCEPTION : send the error for exceptions processing. See Handling Errors as Exceptions for more information.

IGNORE : ignore the error and continue processing.

RETRYOP [MAXRETRIES n ] : retry the operation, optionally up to a specific number of times.

TRANSABORT [, MAXRETRIES n ] [, DELAY[C]SECS n ] : abort the transaction and reposition to the beginning, optionally up to a specific number of times at specific intervals.

RESET : remove all previous REPERROR rules and restore the default of ABEND .

TRANSDISCARD : discard the entire replicated source transaction if any operation within that transaction, including the commit, causes a Replicat error that is listed in the error specification. This option is useful when integrity constraint checking is disabled on the target.

TRANSEXCEPTION : perform exceptions mapping for every record in the replicated source transaction, according to its exceptions-mapping statement, if any operation within that transaction (including the commit) causes a Replicat error that is listed in the error specification.

Most options operate on the individual record that generated an error, and Replicat processes the other, successful operations in the transaction. The exceptions are TRANSDISCARD and TRANSEXCEPTION : These options affect all records in a transaction if any record in that transaction generates an error. (The ABEND option also applies to the entire transaction, but does not apply error handling.)

See Reference for Oracle GoldenGate for REPERROR syntax and usage.

Handling Errors as Exceptions

When the action of REPERROR is EXCEPTION or TRANSEXCEPTION , you can map the values of operations that generate errors to an exceptions table and, optionally, map other information about the error that can be used to resolve the error. See About the Exceptions Table.

To map the exceptions to the exceptions table, use either of the following options of the MAP parameter:

MAP with EXCEPTIONSONLY

MAP with MAPEXCEPTION

Using EXCEPTIONSONLY

EXCEPTIONSONLY is valid for one pair of source and target tables that are explicitly named and mapped one-to-one in a MAP statement; that is, there cannot be wildcards. To use EXCEPTIONSONLY , create two MAP statements for each source table that you want to use EXCEPTIONSONLY for on the target:

The first, a standard MAP statement, maps the source table to the actual target table.

The second, an exceptions MAP statement , maps the source table to the exceptions table (instead of to the target table). An exceptions MAP statement executes immediately after an error on the source table to send the row values to the exceptions table.

To identify a MAP statement as an exceptions MAP statement, use the INSERTALLRECORDS and EXCEPTIONSONLY options. The exceptions MAP statement must immediately follow the regular MAP statement that contains the same source table. Use a COLMAP clause in the exceptions MAP statement if the source and exceptions-table columns are not identical, or if you want to map additional information to extra columns in the exceptions table, such as information that is captured by means of column-conversion functions or SQLEXEC .

For more information about these parameters, see Reference for Oracle GoldenGate .

A regular MAP statement that maps the source table ggs.equip_account to its target table equip_account2.

An exceptions MAP statement that maps the same source table to the exceptions table ggs.equip_account_exception .

In this case, four extra columns were created, in addition to the same columns that the table itself contains:

To populate the DML_DATE column, the @DATENOW column-conversion function is used to get the date and time of the failed operation, and the result is mapped to the column. To populate the other extra columns, the @GETENV function is used to return the operation type, database error number, and database error message.

The EXCEPTIONSONLY option of the exceptions MAP statement causes the statement to execute only after a failed operation on the source table. It prevents every operation from being logged to the exceptions table.

The INSERTALLRECORDS parameter causes all failed operations for the specified source table, no matter what the operation type, to be logged to the exceptions table as inserts .

There can be no primary key or unique index restrictions on the exception table. Uniqueness violations are possible in this scenario and would generate errors.

Example 14-1 EXCEPTIONSONLY

This example shows how to use REPERROR with EXCEPTIONSONLY and an exceptions MAP statement. This example only shows the parameters that relate to REPERROR ; other parameters not related to error handling are also required for Replicat.

In this example, the REPERROR parameter is set for DEFAULT error handling, and the EXCEPTION option causes the Replicat process to treat failed operations as exceptions and continue processing.

Using MAPEXCEPTION

MAPEXCEPTION is valid when the names of the source and target tables in the MAP statement are wildcarded. Place the MAPEXCEPTION clause in the regular MAP statement, the same one where you map the source tables to the target tables. Replicat maps all operations that generate errors from all of the wildcarded tables to the same exceptions table; therefore, the exceptions table should contain a superset of all of the columns in all of the wildcarded tables.

Because you cannot individually map columns in a wildcard configuration, use the COLMAP clause with the USEDEFAULTS option to handle the column mapping for the wildcarded tables (or use the COLMATCH parameter if appropriate), and use explicit column mappings to map any additional information, such as that captured with column-conversion functions or SQLEXEC .

When using MAPEXCEPTION , include the INSERTALLRECORDS parameter in the MAPEXCEPTION clause. INSERTALLRECORDS causes all operation types to be applied to the exceptions table as INSERT operations. This is required to keep an accurate record of the exceptions and to prevent integrity errors on the exceptions table.

For more information about these parameters, see Reference for Oracle GoldenGate .

Example 14-2 MAPEXCEPTION

This is an example of how to use MAPEXCEPTION for exceptions mapping. The MAP and TARGET clauses contain wildcarded source and target table names. Exceptions that occur when processing any table with a name beginning with TRX are captured to the fin.trxexceptions table using the designated mapping.

About the Exceptions Table

Use an exceptions table to capture information about an error that can be used for such purposes as troubleshooting your applications or configuring them to handle the error. At minimum, an exceptions table should contain enough columns to receive the entire row image from the failed operation. You can define extra columns to contain other information that is captured by means of column-conversion functions, SQLEXEC , or other external means.

To ensure that the trail record contains values for all of the columns that you map to the exceptions table, you can use either the LOGALLSUPCOLS parameter or the following parameters in the Extract parameter file:

Use the NOCOMPRESSDELETES parameter so that all columns of a row are written to the trail for DELETE operations.

Use the GETUPDATEBEFORES parameter so that Extract captures the before image of a row and writes them to the trail.

For more information about these parameters, see Reference for Oracle GoldenGate .

Источник

Microsoft distributes Microsoft SQL Server 2008 R2 Service Pack 1 (SP1) fixes as one downloadable file. Because the fixes are cumulative, each new release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 R2 Service Pack 1 (SP1) fix release.

Symptoms

Consider the following scenario:

  • You create a dataset for a Microsoft SQL Server 2008 R2 Reporting Services (SSRS 2008 R2) or Microsoft SQL Server 2012 Report Services (SSRS 2012) report in SQL Server Business Intelligence Development Studio (BIDS).

  • You right-click the dataset and select Dataset Properties in the Report Data pane.

  • In the Dataset Properties dialog box, you select Option. Then, you select Greek or Greek_100 in the Collation drop-down list.

  • You try to preview the SSRS 2008 R2 report.

In this scenario, you receive the following error message:


An error occurred during local report processing.
An error has occurred during report processing.
Culture ID 66568 (0x10408) is not a supported culture.
Parameter name: culture

Resolution

Cumulative update information

Cumulative update package 1 for SQL Server 2012 Service Pack 1

The fix for this issue was first released in Cumulative Update 1. For more information about how to obtain this cumulative update package for SQL Server 2012 Service Pack 1, click the following article number to view the article in the Microsoft Knowledge Base:

2765331 Cumulative update package 1 for SQL Server 2012 Service Pack 1Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2012 fix release. We recommend that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2772858 The SQL Server 2012 builds that were released after SQL Server 2012 Service Pack 1 was released

SQL Server 2012

The fix for this issue was first released in Cumulative Update 3 for SQL Server 2012. For more information about this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2723749 Cumulative update package 3 for SQL Server 2012Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2012 fix release. Microsoft recommends that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2692828 The SQL Server 2012 builds that were released after SQL Server 2012 was released You must apply a SQL Server 2012 hotfix to an installation of SQL Server 2012.

SQL Server 2008 R2 Service Pack 2


The fix for this issue was first released in Cumulative Update 1 for SQL Server 2008 R2 Service Pack 2. For more information about how to obtain this cumulative update package, click the following article number to view the article in the Microsoft Knowledge Base:

2720425 Cumulative Update package 1 for SQL Server 2008 R2 Service Pack 2Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 R2 fix release. We recommend that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2730301 The SQL Server 2008 R2 builds that were released after SQL Server 2008 R2 Service Pack 2 was released

SQL Server 2008 R2 SP1

The fix for this issue was first released in Cumulative Update package 7 for SQL Server 2008 R2 SP1. For more information about how to obtain this cumulative update package for SQL Server 2008 R2 SP1, click the following article number to view the article in the Microsoft Knowledge Base:

2703282 Cumulative update package 7 for SQL Server 2008 R2 SP1Note Because the builds are cumulative, each new fix release contains all the hotfixes and all the security fixes that were included with the previous SQL Server 2008 R2 SP1 fix release. We recommend that you consider applying the most recent fix release that contains this hotfix. For more information, click the following article number to view the article in the Microsoft Knowledge Base:

2567616 The SQL Server 2008 R2 builds that were released after SQL Server 2008 R2 Service Pack 1 was released

Status

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the «Applies to» section.

Need more help?

Handling Errors in Elastic Transcoder

Topics

  • API Error Codes (Client and Server Errors)
  • Errors During Job Processing
  • Catching Errors
  • Error Retries and Exponential Backoff

When you send requests to and get responses from the Elastic Transcoder API, you might encounter two types of API errors:

  • Client errors: Client errors are indicated by a 4xx HTTP response code. Client errors indicate that Elastic Transcoder found a problem with the client request, such as an authentication failure or missing required parameters. Fix the issue in the client application before submitting the request again.
  • Server errors: Server errors are indicated by a 5xx HTTP response code, and need to be resolved by Amazon. You can resubmit/retry the request until it succeeds.

For each API error, Elastic Transcoder returns the following values:

  • A status code, for example, 400
  • An error code, for example, ValidationException
  • An error message, for example, Supplied AttributeValue is empty, must contain exactly one of the supported datatypes

For a list of error codes that Elastic Transcoder returns for client and server errors, see API Error Codes (Client and Server Errors).

In addition, you might encounter errors while Elastic Transcoder is processing your job. For more information, see Errors During Job Processing.

API Error Codes (Client and Server Errors)

HTTP status codes indicate whether an operation is successful or not.

A response code of 200 indicates the operation was successful. Other error codes indicate either a client error (4xx) or a server error (5xx).

The following table lists the errors returned by Elastic Transcoder. Some errors are resolved if you simply retry the same request. The table indicates which errors are likely to be resolved with successive retries. If the value of the Retry column is:

  • Yes: Submit the same request again.
  • No: Fix the problem on the client side before submitting a new request.

For more information about retrying requests, see Error Retries and Exponential Backoff.

HTTP Status Code Error code Message Cause Retry
400 Conditional Check Failed Exception The conditional request failed. Example: The expected value did not match what was stored in the system. No
400 Incomplete Signature Exception The request signature does not conform to AWS standards. The signature in the request did not include all of the required components. See HTTP Header Contents. No
403 Missing Authentication Token Exception The request must contain a valid (registered) AWS Access Key ID. The request did not include the required x-amz-security-token. See Making HTTP Requests to Elastic Transcoder. No
400 Validation Exception Various. One or more values in a request were missing or invalid; for example, a value was empty or was greater than the maximum valid value. No
403 AccessDenied Exception [See the AWS documentation website for more details] You attempted to delete a system preset, the signature in a call to the Elastic Transcoder API was invalid, or an IAM user is not authorized to perform the operation. No
404 ResourceNot Found Exception [See the AWS documentation website for more details] Example: The pipeline to which you’re trying to add a job doesn’t exist or is still being created. No
409 Resource InUse Exception [See the AWS documentation website for more details] Example: You attempted to delete a pipeline that is currently in use. No
429 Limit Exceeded Exception [See the AWS documentation website for more details] The current AWS account has exceeded limits on Elastic Transcoder objects. For more information, see Limits on the Number of Elastic Transcoder Pipelines, Jobs, and Presets.
429 Provisioned Throughput Exceeded Exception You exceeded your maximum allowed provisioned throughput. Example: Your request rate is too high. The AWS SDKs for Elastic Transcoder automatically retry requests that receive this exception. Your request is eventually successful unless your retry queue is too large to finish. Reduce the frequency of requests. For more information, see Error Retries and Exponential Backoff. If you’re polling to determine the status of a request, consider using notifications to determine status. For more information, see Notifications of Job Status. Yes
429 Throttling Exception Rate of requests exceeds the allowed throughput. You are submitting requests too rapidly; for example, requests to create new jobs. If you’re polling to determine the status of a request, consider using notifications to determine status. For more information, see Notifications of Job Status. Yes
500 Internal Failure The server encountered an internal error trying to fulfill the request. The server encountered an error while processing your request. Yes
500 Internal Server Error The server encountered an internal error trying to fulfill the request. The server encountered an error while processing your request. Yes
500 Internal Service Exception The service encountered an unexpected exception while trying to fulfill the request. Yes
500 Service Unavailable Exception The service is currently unavailable or busy. There was an unexpected error on the server while processing your request. Yes

Sample Error Response

The following is an HTTP response indicating that the value for inputBucket was null, which is not a valid value.

HTTP/1.1 400 Bad Request
x-amzn-RequestId: b0e91dc8-3807-11e2-83c6-5912bf8ad066
x-amzn-ErrorType: ValidationException
Content-Type: application/json
Content-Length: 124
Date: Mon, 26 Nov 2012 20:27:25 GMT

{"message":"1 validation error detected: Value null at 'inputBucket' failed to satisfy constraint: Member must not be null"}

Errors During Job Processing

When Elastic Transcoder encounters an error while processing your job, it reports the error in two ways:

  • Job Status and Output Status: Elastic Transcoder sets the Job:Status object and the Outputs:Status object for the failed output to Error. In addition, Elastic Transcoder sets the Outputs:StatusDetail JSON object for the failed output to a value that explains the failure.

  • SNS Notification: If you configured the pipeline to send an SNS notification when Elastic Transcoder encounters an error during processing, Elastic Transcoder includes a JSON object in the notification in the following format:

    {
       "state" : "PROGRESSING|COMPLETED|WARNING|ERROR",
       "errorCode" : "the code of any error that occurred",
       "messageDetails" : "the notification message you created in Amazon SNS",
       "version" : "API version that you used to create the job",
       "jobId" : "value of Job:Id object that Elastic Transcoder 
                 returns in the response to a Create Job request",
       "pipelineId" : "value of PipelineId object 
                      in the Create Job request",
       "input" : {
          job Input settings
       },
       "outputKeyPrefix" : "prefix for file names in Amazon S3 bucket",
       "outputs": [
          {
             applicable job Outputs settings,
             "status" : "Progressing|Complete|Warning|Error"
          },
          {...}
       ],
       "playlists": [
          {
             applicable job playlists settings
          }
       ],
       "userMetadata": {
          "metadata key": "metadata value"
       }
    }
    
Value of errorCode Value of messageDetails Cause
1000 Validation Error While processing the job, Elastic Transcoder determined that one or more values in the request were invalid.
1001 Dependency Error Elastic Transcoder could not generate the playlist because it encountered an error with one or more of the playlists dependencies.
2000 Cannot Assume Role Elastic Transcoder cannot assume the AWS Identity and Access Management role that is specified in the Role object in the pipeline for this job.
3000 Unclassified Storage Error
3001 Input Does Not Exist No file exists with the name that you specified in the Input:Key object for this job. The file must exist in the Amazon S3 bucket that is specified in the InputBucket object in the pipeline for this job.
3002 Output Already Exists A file already exists with the name that you specified in the Outputs:Key (or Output:Key) object for this job. The file cannot exist in the Amazon S3 bucket that is specified in the OutputBucket object in the pipeline for this job.
3003 Does Not Have Read Permission The IAM role specified in the Role object in the pipeline that you used for this job doesn’t have permission to read from the Amazon S3 bucket that contains the file you want to transcode.
3004 Does Not Have Write Permission The IAM role specified in the Role object in the pipeline that you used for this job doesn’t have permission to write to the Amazon S3 bucket in which you want to save either transcoded files or thumbnail files.
3005 Bucket Does Not Exist The specified S3 bucket does not exist: bucket={1}.
3006 Does Not Have Write Permission Elastic Transcoder was unable to write the key={1} to bucket={2}, as the key is not in the same region as the bucket
4000 Bad Input File The file that you specified in the Input:Key object for this job is in a format that is currently not supported by Elastic Transcoder.
4001 Bad Input File The width x height of the file that you specified in the Input:Key object for this job exceeds the maximum allowed width x height.
4002 Bad Input File The file size of the file that you specified in the Input:Key object for this job exceeds the maximum allowed size.
4003 Bad Input File Elastic Transcoder couldn’t interpret the file that you specified in one of the Outputs:Watermarks:InputKey objects for this job.
4004 Bad Input File The width x height of a file that you specified in one of the Outputs:Watermarks:InputKey objects for this job exceeds the maximum allowed width x height.
4005 Bad Input File The size of a file that you specified for one of the {1} objects exceeds the maximum allowed size: bucket={2}, key={3}, size{4}, max size={5}.
4006 Bad Input File Elastic Transcoder could not transcode the input file because the format is not supported.
4007 Unhandled Input File Elastic Transcoder encountered a file type that is generally supported, but was unable to process the file correctly. This error automatically opened a support case, and we have started to research the cause of the problem.
4008 Bad Input File The underlying cause of this is a mismatch between the preset and the input file. Examples include: [See the AWS documentation website for more details]
4009 Bad Input File Elastic Transcoder was unable to insert all of your album art into the output file because you exceeded the maximum number of artwork streams.
4010 Bad Input File Elastic Transcoder could not interpret the graphic file you specified for AlbumArt:Artwork:InputKey.
4011 Bad Input File Elastic Transcoder detected an embedded artwork stream, but could not interpret it.
4012 Bad Input File The image that you specified for AlbumArt:Artwork exceeds the maximum allowed width x height: 4096 x 3072.
4013 Bad Input File The width x height of the embedded artwork exceeds the maximum allowed width x height: 4096 x 3072.
4014 Bad Input The value that you specified for starting time of a clip is after the end of the input file. Elastic Transcoder could not create an output file.
4015 Bad Input Elastic Transcoder could not generate a manifest file because the generated segments did not match.
4016 Bad Input Elastic Transcoder could not decrypt the input file from {1} using {2}.
4017 Bad Input The AES key was encrypted with a {2}-bit encryption key. AES supports only 128-, 192-, and 256-bit encryption keys. MD5={1}.
4018 Bad Input Elastic Transcoder was unable to decrypt the ciphered key with MD5={1}
4019 Bad Input Elastic Transcoder was unable to generate a data key using the KMS key ARN {0}.
4020 Bad Input Your key must be 128 bits for AES-128 encryption. MD5={1}, {2} bits.
4021 Bad Input Your key must be 128 bits for PlayReady DRM. MD5={1}, strength={2} bits.
4022 Bad Input The combined size of the {1} specified media files exceeds the maximum allowed size: bucket={2}, size={3}.
4023 Bad Input The {1} input files specified for concatenation will not create an output with a consistent resolution with the specified preset. Use a preset with different PaddingPolicy, SizingPolicy, MaxWidth, and MaxHeight settings.
4024 Bad Input The {1} input files specified for concatenation will not create thumbnails with a consistent resolution with the specified preset. Use a preset with different thumbnail PaddingPolicy, SizingPolicy, MaxWidth, and MaxHeight settings.
4025 Bad Input At least one media file (input #{1}) doesn’t match the others. All media files must have either video or no video.
4026 Bad Input At least one media file (input #{1}) doesn’t match the others. All media files must have either audio or no audio.
4100 Bad Input File Elastic Transcoder detected an embedded caption track but could not interpret it.
4101 Bad Input File Elastic Transcoder could not interpret the specified caption file for Amazon S3 bucket={1}, key={2}.
4102 Bad Input File Elastic Transcoder could not interpret the specified caption file since it was not UTF-8 encoded: Amazon S3 bucket={1}, key={2}.
4103 Bad Input File Elastic Transcoder was unable to process all of your caption tracks because you exceeded {1}, the maximum number of caption tracks.
4104 Bad Input File Elastic Transcoder could not generate a master playlist because the desired output contains {1} embedded captions, when the maximum is 4.
4105 Bad Input File Elastic Transcoder cannot embed your caption tracks because frame rate {1} is not supported for CEA-708 — only frame rates [29.97, 30] are supported.
4106 Bad Input File Elastic Transcoder cannot embed your caption tracks because format {1} supports only {2} caption track(s).
9000 Internal Service Error
9001 Internal Service Error
9999 Internal Service Error

Catching Errors

For your application to run smoothly, you need to build in logic to catch and respond to errors. One typical approach is to implement your request within a try block or if-then statement.

The AWS SDKs perform their own retries and error checking. If you encounter an error while using one of the AWS SDKs, you should see the error code and description. You should also see a Request ID value. The Request ID value can help troubleshoot problems with Elastic Transcoder support.

The following example uses the AWS SDK for Java to delete an item within a try block and uses a catch block to respond to the error. In this case, it warns the user that the request failed. The example uses the AmazonServiceException class to retrieve information about any operation errors, including the Request ID. The example also uses the AmazonClientException class in case the request is not successful for other reasons.

try {
   DeleteJobRequest request = new DeleteJobRequest(jobId);
   DeleteJobResult result = ET.deleteJob(request);
   System.out.println("Result: " + result);
   // Get error information from the service while trying to run the operation	
   }  catch (AmazonServiceException ase) {
      System.err.println("Failed to delete job " + jobId);
      // Get specific error information
      System.out.println("Error Message:    " + ase.getMessage());
      System.out.println("HTTP Status Code: " + ase.getStatusCode());
      System.out.println("AWS Error Code:   " + ase.getErrorCode());
      System.out.println("Error Type:       " + ase.getErrorType());
      System.out.println("Request ID:       " + ase.getRequestId());
   // Get information in case the operation is not successful for other reasons	
   }  catch (AmazonClientException ace) {
      System.out.println("Caught an AmazonClientException, which means"+
      " the client encountered " +
      "an internal error while trying to " +
      "communicate with Elastic Transcoder, " +
      "such as not being able to access the network.");
      System.out.println("Error Message: " + ace.getMessage());
   }

Error Retries and Exponential Backoff

Numerous components on a network, such as DNS servers, switches, load balancers, and others can generate errors anywhere in the life of a given request.

The usual technique for dealing with these error responses in a networked environment is to implement retries in the client application. This technique increases the reliability of the application and reduces operational costs for the developer.

Each AWS SDK supporting Elastic Transcoder implements automatic retry logic. The AWS SDK for Java automatically retries requests, and you can configure the retry settings using the ClientConfiguration class. For example, in some cases, such as a web page making a request with minimal latency and no retries, you might want to turn off the retry logic. Use the ClientConfiguration class and provide a maxErrorRetry value of 0 to turn off the retries.

If you’re not using an AWS SDK, you should retry original requests that receive server errors (5xx). However, client errors (4xx, other than a ThrottlingException or a ProvisionedThroughputExceededException) indicate you need to revise the request itself to correct the problem before trying again.

Note
If you’re polling to determine the status of a request, and if Elastic Transcoder is returning HTTP status code 429 with an error code of Provisioned Throughput Exceeded Exception or Throttling Exception, consider using notifications instead of polling to determine status. For more information, see Notifications of Job Status.

In addition to simple retries, we recommend using an exponential backoff algorithm for better flow control. The idea behind exponential backoff is to use progressively longer waits between retries for consecutive error responses. For example, you might let one second elapse before the first retry, four seconds before the second retry, 16 seconds before the third retry, and so on. However, if the request has not succeeded after a minute, the problem might be a hard limit and not the request rate. For example, you may have reached the maximum number of pipelines allowed. Set the maximum number of retries to stop around one minute.

Following is a workflow showing retry logic. The workflow logic first determines if the error is a server error (5xx). Then, if the error is a server error, the code retries the original request.

currentRetry = 0
DO
  set retry to false

  execute Elastic Transcoder request

  IF Exception.errorCode = ProvisionedThroughputExceededException
    set retry to true
  ELSE IF Exception.httpStatusCode = 500
    set retry to true
  ELSE IF Exception.httpStatusCode = 400
    set retry to false 
    fix client error (4xx)

  IF retry = true  
    wait for (2^currentRetry * 50) milliseconds
    currentRetry = currentRetry + 1

WHILE (retry = true AND currentRetry < MaxNumberOfRetries)  // limit retries

Hello,

Been using Authorize.net for a few years now without issue.  Using John Conde’s PHP class to handle all of my transactions.  We use CIM to manage customer profiles, addresses, etc.

Recently we have been having an issue when attempting to capture a charge.  The API returns:

Error Code: E00001 Error Message: An error occurred during processing. Please try again.

Where the Error Code is $cim->getCode() and the Error Message is $cim->getResponse().

So we wait a few minutes and try again, the charge is successful.  The problem is the first attempt that returned the error ends up getting charged to the customer’s card as well.

So far this has happened twice in the last 2-3 weeks of approximately 1500 charge attempts. While this is a small amount it is unacceptable.  We’ve had to take the time to go over the charge logs to make sure this isn’t happening elsewhere.

My question is, is there a way to catch this?  I thought I was looking at all the appropriate places for error codes and such but am a bit stymied on how to catch this.

If I try to get the results using $cim->getResults() it returns an empty array.

Any suggestions or help would be appreciated.

pete

Время прочтения
16 мин

Просмотры 35K

Привет, Хабр! Представляю вашему вниманию перевод статьи «Error and Transaction Handling in SQL Server. Part One – Jumpstart Error Handling» автора Erland Sommarskog.

1. Введение

Эта статья – первая в серии из трёх статей, посвященных обработке ошибок и транзакций в SQL Server. Её цель – дать вам быстрый старт в теме обработки ошибок, показав базовый пример, который подходит для большей части вашего кода. Эта часть написана в расчете на неопытного читателя, и по этой причине я намеренно умалчиваю о многих деталях. В данный момент задача состоит в том, чтобы рассказать как без упора на почему. Если вы принимаете мои слова на веру, вы можете прочесть только эту часть и отложить остальные две для дальнейших этапов в вашей карьере.

С другой стороны, если вы ставите под сомнение мои рекомендации, вам определенно необходимо прочитать две остальные части, где я погружаюсь в детали намного более глубоко, исследуя очень запутанный мир обработки ошибок и транзакций в SQL Server. Вторая и третья части, так же, как и три приложения, предназначены для читателей с более глубоким опытом. Первая статья — короткая, вторая и третья значительно длиннее.

Все статьи описывают обработку ошибок и транзакций в SQL Server для версии 2005 и более поздних версий.

1.1 Зачем нужна обработка ошибок?

Почему мы обрабатываем ошибки в нашем коде? На это есть много причин. Например, на формах в приложении мы проверяем введенные данные и информируем пользователей о допущенных при вводе ошибках. Ошибки пользователя – это предвиденные ошибки. Но нам также нужно обрабатывать непредвиденные ошибки. То есть, ошибки могут возникнуть из-за того, что мы что-то упустили при написании кода. Простой подход – это прервать выполнение или хотя бы вернуться на этап, в котором мы имеем полный контроль над происходящим. Недостаточно будет просто подчеркнуть, что совершенно непозволительно игнорировать непредвиденные ошибки. Это недостаток, который может вызвать губительные последствия: например, стать причиной того, что приложение будет предоставлять некорректную информацию пользователю или, что еще хуже, сохранять некорректные данные в базе. Также важно сообщать о возникновении ошибки с той целью, чтобы пользователь не думал о том, что операция прошла успешно, в то время как ваш код на самом деле ничего не выполнил.

Мы часто хотим, чтобы в базе данных изменения были атомарными. Например, задача по переводу денег с одного счета на другой. С этой целью мы должны изменить две записи в таблице CashHoldings и добавить две записи в таблицу Transactions. Абсолютно недопустимо, чтобы ошибки или сбой привели к тому, что деньги будут переведены на счет получателя, а со счета отправителя они не будут списаны. По этой причине обработка ошибок также касается и обработки транзакций. В приведенном примере нам нужно обернуть операцию в BEGIN TRANSACTION и COMMIT TRANSACTION, но не только это: в случае ошибки мы должны убедиться, что транзакция откачена.

2. Основные команды

Мы начнем с обзора наиболее важных команд, которые необходимы для обработки ошибок. Во второй части я опишу все команды, относящиеся к обработке ошибок и транзакций.

2.1 TRY-CATCH

Основным механизмом обработки ошибок является конструкция TRY-CATCH, очень напоминающая подобные конструкции в других языках. Структура такова:

BEGIN TRY
   <обычный код>
END TRY
BEGIN CATCH
   <обработка ошибок>
END CATCH

Если какая-либо ошибка появится в <обычный код>, выполнение будет переведено в блок CATCH, и будет выполнен код обработки ошибок.

Как правило, в CATCH откатывают любую открытую транзакцию и повторно вызывают ошибку. Таким образом, вызывающая клиентская программа понимает, что что-то пошло не так. Повторный вызов ошибки мы обсудим позже в этой статье.

Вот очень быстрый пример:

BEGIN TRY
   DECLARE @x int
   SELECT @x = 1/0
   PRINT 'Not reached'
END TRY
BEGIN CATCH 
   PRINT 'This is the error: ' + error_message()
END CATCH

Результат выполнения: This is the error: Divide by zero error encountered.

Мы вернемся к функции error_message() позднее. Стоит отметить, что использование PRINT в обработчике CATCH приводится только в рамках экспериментов и не следует делать так в коде реального приложения.

Если <обычный код> вызывает хранимую процедуру или запускает триггеры, то любая ошибка, которая в них возникнет, передаст выполнение в блок CATCH. Если более точно, то, когда возникает ошибка, SQL Server раскручивает стек до тех пор, пока не найдёт обработчик CATCH. И если такого обработчика нет, SQL Server отправляет сообщение об ошибке напрямую клиенту.

Есть одно очень важное ограничение у конструкции TRY-CATCH, которое нужно знать: она не ловит ошибки компиляции, которые возникают в той же области видимости. Рассмотрим пример:

CREATE PROCEDURE inner_sp AS
   BEGIN TRY
      PRINT 'This prints'
      SELECT * FROM NoSuchTable
      PRINT 'This does not print'
   END TRY
   BEGIN CATCH
      PRINT 'And nor does this print'
   END CATCH
go
EXEC inner_sp

Выходные данные:

This prints
Msg 208, Level 16, State 1, Procedure inner_sp, Line 4
Invalid object name 'NoSuchTable'

Как можно видеть, блок TRY присутствует, но при возникновении ошибки выполнение не передается блоку CATCH, как это ожидалось. Это применимо ко всем ошибкам компиляции, таким как пропуск колонок, некорректные псевдонимы и тому подобное, которые возникают во время выполнения. (Ошибки компиляции могут возникнуть в SQL Server во время выполнения из-за отложенного разрешения имен – особенность, благодаря которой SQL Server позволяет создать процедуру, которая обращается к несуществующим таблицам.)

Эти ошибки не являются полностью неуловимыми; вы не можете поймать их в области, в которой они возникают, но вы можете поймать их во внешней области. Добавим такой код к предыдущему примеру:

CREATE PROCEDURE outer_sp AS
   BEGIN TRY
      EXEC inner_sp
   END TRY
   BEGIN CATCH
      PRINT 'The error message is: ' + error_message()
   END CATCH
go
EXEC outer_sp

Теперь мы получим на выходе это:

This prints
The error message is: Invalid object name 'NoSuchTable'.

На этот раз ошибка была перехвачена, потому что сработал внешний обработчик CATCH.

2.2 SET XACT_ABORT ON

В начало ваших хранимых процедур следует всегда добавлять это выражение:

SET XACT_ABORT, NOCOUNT ON

Оно активирует два параметра сессии, которые выключены по умолчанию в целях совместимости с предыдущими версиями, но опыт доказывает, что лучший подход – это иметь эти параметры всегда включенными. Поведение SQL Server по умолчанию в той ситуации, когда не используется TRY-CATCH, заключается в том, что некоторые ошибки прерывают выполнение и откатывают любые открытые транзакции, в то время как с другими ошибками выполнение последующих инструкций продолжается. Когда вы включаете XACT_ABORT ON, почти все ошибки начинают вызывать одинаковый эффект: любая открытая транзакция откатывается, и выполнение кода прерывается. Есть несколько исключений, среди которых наиболее заметным является выражение RAISERROR.

Параметр XACT_ABORT необходим для более надежной обработки ошибок и транзакций. В частности, при настройках по умолчанию есть несколько ситуаций, когда выполнение может быть прервано без какого-либо отката транзакции, даже если у вас есть TRY-CATCH. Мы видели такой пример в предыдущем разделе, где мы выяснили, что TRY-CATCH не перехватывает ошибки компиляции, возникшие в той же области. Открытая транзакция, которая не была откачена из-за ошибки, может вызвать серьезные проблемы, если приложение работает дальше без завершения транзакции или ее отката.

Для надежной обработки ошибок в SQL Server вам необходимы как TRY-CATCH, так и SET XACT_ABORT ON. Среди них инструкция SET XACT_ABORT ON наиболее важна. Если для кода на промышленной среде только на нее полагаться не стоит, то для быстрых и простых решений она вполне подходит.

Параметр NOCOUNT не имеет к обработке ошибок никакого отношения, но включение его в код является хорошей практикой. NOCOUNT подавляет сообщения вида (1 row(s) affected), которые вы можете видеть в панели Message в SQL Server Management Studio. В то время как эти сообщения могут быть полезны при работе c SSMS, они могут негативно повлиять на производительность в приложении, так как увеличивают сетевой трафик. Сообщение о количестве строк также может привести к ошибке в плохо написанных клиентских приложениях, которые могут подумать, что это данные, которые вернул запрос.

Выше я использовал синтаксис, который немного необычен. Большинство людей написали бы два отдельных выражения:

SET NOCOUNT ON
SET XACT_ABORT ON

Между ними нет никакого отличия. Я предпочитаю версию с SET и запятой, т.к. это снижает уровень шума в коде. Поскольку эти выражения должны появляться во всех ваших хранимых процедурах, они должны занимать как можно меньше места.

3. Основной пример обработки ошибок

После того, как мы посмотрели на TRY-CATCH и SET XACT_ABORT ON, давайте соединим их вместе в примере, который мы можем использовать во всех наших хранимых процедурах. Для начала я покажу пример, в котором ошибка генерируется в простой форме, а в следующем разделе я рассмотрю решения получше.

Для примера я буду использовать эту простую таблицу.

CREATE TABLE sometable(a int NOT NULL,
                       b int NOT NULL,
                       CONSTRAINT pk_sometable PRIMARY KEY(a, b))

Вот хранимая процедура, которая демонстрирует, как вы должны работать с ошибками и транзакциями.

CREATE PROCEDURE insert_data @a int, @b int AS 
   SET XACT_ABORT, NOCOUNT ON
   BEGIN TRY
      BEGIN TRANSACTION
      INSERT sometable(a, b) VALUES (@a, @b)
      INSERT sometable(a, b) VALUES (@b, @a)
      COMMIT TRANSACTION
   END TRY
   BEGIN CATCH
      IF @@trancount > 0 ROLLBACK TRANSACTION
      DECLARE @msg nvarchar(2048) = error_message()  
      RAISERROR (@msg, 16, 1)
      RETURN 55555
   END CATCH

Первая строка в процедуре включает XACT_ABORT и NOCOUNT в одном выражении, как я показывал выше. Эта строка – единственная перед BEGIN TRY. Все остальное в процедуре должно располагаться после BEGIN TRY: объявление переменных, создание временных таблиц, табличных переменных, всё. Даже если у вас есть другие SET-команды в процедуре (хотя причины для этого встречаются редко), они должны идти после BEGIN TRY.

Причина, по которой я предпочитаю указывать SET XACT_ABORT и NOCOUNT перед BEGIN TRY, заключается в том, что я рассматриваю это как одну строку шума: она всегда должна быть там, но я не хочу, чтобы это мешало взгляду. Конечно же, это дело вкуса, и если вы предпочитаете ставить SET-команды после BEGIN TRY, ничего страшного. Важно то, что вам не следует ставить что-либо другое перед BEGIN TRY.

Часть между BEGIN TRY и END TRY является основной составляющей процедуры. Поскольку я хотел использовать транзакцию, определенную пользователем, я ввел довольно надуманное бизнес-правило, в котором говорится, что если вы вставляете пару, то обратная пара также должна быть вставлена. Два выражения INSERT находятся внутри BEGIN и COMMIT TRANSACTION. Во многих случаях у вас будет много строк кода между BEGIN TRY и BEGIN TRANSACTION. Иногда у вас также будет код между COMMIT TRANSACTION и END TRY, хотя обычно это только финальный SELECT, возвращающий данные или присваивающий значения выходным параметрам. Если ваша процедура не выполняет каких-либо изменений или имеет только одно выражение INSERT/UPDATE/DELETE/MERGE, то обычно вам вообще не нужно явно указывать транзакцию.

В то время как блок TRY будет выглядеть по-разному от процедуры к процедуре, блок CATCH должен быть более или менее результатом копирования и вставки. То есть вы делаете что-то короткое и простое и затем используете повсюду, не особо задумываясь. Обработчик CATCH, приведенный выше, выполняет три действия:

  1. Откатывает любые открытые транзакции.
  2. Повторно вызывает ошибку.
  3. Убеждается, что возвращаемое процедурой значение отлично от нуля.

Эти три действия должны всегда быть там. Мы можете возразить, что строка

IF @@trancount > 0 ROLLBACK TRANSACTION

не нужна, если нет явной транзакции в процедуре, но это абсолютно неверно. Возможно, вы вызываете хранимую процедуру, которая открывает транзакцию, но которая не может ее откатить из-за ограничений TRY-CATCH. Возможно, вы или кто-то другой добавите явную транзакцию через два года. Вспомните ли вы тогда о том, что нужно добавить строку с откатом? Не рассчитывайте на это. Я также слышу читателей, которые возражают, что если тот, кто вызывает процедуру, открыл транзакцию, мы не должны ее откатывать… Нет, мы должны, и если вы хотите знать почему, вам нужно прочитать вторую и третью части. Откат транзакции в обработчике CATCH – это категорический императив, у которого нет исключений.

Код повторной генерации ошибки включает такую строку:

DECLARE @msg nvarchar(2048) = error_message()

Встроенная функция error_message() возвращает текст возникшей ошибки. В следующей строке ошибка повторно вызывается с помощью выражения RAISERROR. Это не самый простой способ вызова ошибки, но он работает. Другие способы мы рассмотрим в следующей главе.

Замечание: синтаксис для присвоения начального значения переменной в DECLARE был внедрен в SQL Server 2008. Если у вас SQL Server 2005, вам нужно разбить строку на DECLARE и выражение SELECT.

Финальное выражение RETURN – это страховка. RAISERROR никогда не прерывает выполнение, поэтому выполнение следующего выражения будет продолжено. Пока все процедуры используют TRY-CATCH, а также весь клиентский код обрабатывает исключения, нет повода для беспокойства. Но ваша процедура может быть вызвана из старого кода, написанного до SQL Server 2005 и до внедрения TRY-CATCH. В те времена лучшее, что мы могли делать, это смотреть на возвращаемые значения. То, что вы возвращаете с помощью RETURN, не имеет особого значения, если это не нулевое значение (ноль обычно обозначает успешное завершение работы).

Последнее выражение в процедуре – это END CATCH. Никогда не следует помещать какой-либо код после END CATCH. Кто-нибудь, читающий процедуру, может не увидеть этот кусок кода.

После прочтения теории давайте попробуем тестовый пример:

EXEC insert_data 9, NULL

Результат выполнения:

Msg 50000, Level 16, State 1, Procedure insert_data, Line 12
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.

Давайте добавим внешнюю процедуру для того, чтобы увидеть, что происходит при повторном вызове ошибки:

CREATE PROCEDURE outer_sp @a int, @b int AS
   SET XACT_ABORT, NOCOUNT ON
   BEGIN TRY
      EXEC insert_data @a, @b
   END TRY
   BEGIN CATCH
      IF @@trancount > 0 ROLLBACK TRANSACTION
      DECLARE @msg nvarchar(2048) = error_message()
      RAISERROR (@msg, 16, 1)
      RETURN 55555
   END CATCH
go
EXEC outer_sp 8, 8

Результат работы:

Msg 50000, Level 16, State 1, Procedure outer_sp, Line 9
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).

Мы получили корректное сообщение об ошибке, но если вы посмотрите на заголовки этого сообщения и на предыдущее поближе, то можете заметить проблему:

Msg 50000, Level 16, State 1, Procedure insert_data, Line 12
Msg 50000, Level 16, State 1, Procedure outer_sp, Line 9

Сообщение об ошибке выводит информацию о расположении конечного выражения RAISERROR. В первом случае некорректен только номер строки. Во втором случае некорректно также имя процедуры. Для простых процедур, таких как наш тестовый пример, это не является большой проблемой. Но если у вас есть несколько уровней вложенных сложных процедур, то наличие сообщения об ошибке с отсутствием указания на место её возникновения сделает поиск и устранение ошибки намного более сложным делом. По этой причине желательно генерировать ошибку таким образом, чтобы можно было определить нахождение ошибочного фрагмента кода быстро, и это то, что мы рассмотрим в следующей главе.

4. Три способа генерации ошибки

4.1 Использование error_handler_sp

Мы рассмотрели функцию error_message(), которая возвращает текст сообщения об ошибке. Сообщение об ошибке состоит из нескольких компонентов, и существует своя функция error_xxx() для каждого из них. Мы можем использовать их для повторной генерации полного сообщения, которое содержит оригинальную информацию, хотя и в другом формате. Если делать это в каждом обработчике CATCH, это будет большой недостаток — дублирование кода. Вам не обязательно находиться в блоке CATCH для вызова error_message() и других подобных функций, и они вернут ту же самую информацию, если будут вызваны из хранимой процедуры, которую выполнит блок CATCH.

Позвольте представить вам error_handler_sp:

CREATE PROCEDURE error_handler_sp AS
 
   DECLARE @errmsg   nvarchar(2048),
           @severity tinyint,
           @state    tinyint,
           @errno    int,
           @proc     sysname,
           @lineno   int
           
   SELECT @errmsg = error_message(), @severity = error_severity(),
          @state  = error_state(), @errno = error_number(),
          @proc   = error_procedure(), @lineno = error_line()
       
   IF @errmsg NOT LIKE '***%'
   BEGIN
      SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') + 
                       ', Line ' + ltrim(str(@lineno)) + '. Errno ' + 
                       ltrim(str(@errno)) + ': ' + @errmsg
   END
   RAISERROR('%s', @severity, @state, @errmsg)

Первое из того, что делает error_handler_sp – это сохраняет значение всех error_xxx() функций в локальные переменные. Я вернусь к выражению IF через секунду. Вместо него давайте посмотрим на выражение SELECT внутри IF:

SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') + 
                 ', Line ' + ltrim(str(@lineno)) + '. Errno ' + 
                 ltrim(str(@errno)) + ': ' + @errmsg

Цель этого SELECT заключается в форматировании сообщения об ошибке, которое передается в RAISERROR. Оно включает в себя всю информацию из оригинального сообщения об ошибке, которое мы не можем вставить напрямую в RAISERROR. Мы должны обработать имя процедуры, которое может быть NULL для ошибок в обычных скриптах или в динамическом SQL. Поэтому используется функция COALESCE. (Если вы не понимаете форму выражения RAISERROR, я рассказываю о нем более детально во второй части.)

Отформатированное сообщение об ошибке начинается с трех звездочек. Этим достигаются две цели: 1) Мы можем сразу видеть, что это сообщение вызвано из обработчика CATCH. 2) Это дает возможность для error_handler_sp отфильтровать ошибки, которые уже были сгенерированы один или более раз, с помощью условия NOT LIKE ‘***%’ для того, чтобы избежать изменения сообщения во второй раз.

Вот как обработчик CATCH должен выглядеть, когда вы используете error_handler_sp:

BEGIN CATCH
   IF @@trancount > 0 ROLLBACK TRANSACTION
   EXEC error_handler_sp
   RETURN 55555
END CATCH

Давайте попробуем несколько тестовых сценариев.

EXEC insert_data 8, NULL
EXEC outer_sp 8, 8

Результат выполнения:

Msg 50000, Level 16, State 2, Procedure error_handler_sp, Line 20
*** [insert_data], Line 5. Errno 515: Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 50000, Level 14, State 1, Procedure error_handler_sp, Line 20
*** [insert_data], Line 6. Errno 2627: Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).

Заголовки сообщений говорят о том, что ошибка возникла в процедуре error_handler_sp, но текст сообщений об ошибках дает нам настоящее местонахождение ошибки – как название процедуры, так и номер строки.

Я покажу еще два метода вызова ошибок. Однако error_handler_sp является моей главной рекомендацией для читателей, которые читают эту часть. Это — простой вариант, который работает на всех версиях SQL Server начиная с 2005. Существует только один недостаток: в некоторых случаях SQL Server генерирует два сообщения об ошибках, но функции error_xxx() возвращают только одну из них, и поэтому одно из сообщений теряется. Это может быть неудобно при работе с административными командами наподобие BACKUPRESTORE, но проблема редко возникает в коде, предназначенном чисто для приложений.

4.2. Использование ;THROW

В SQL Server 2012 Microsoft представил выражение ;THROW для более легкой обработки ошибок. К сожалению, Microsoft сделал серьезную ошибку при проектировании этой команды и создал опасную ловушку.

С выражением ;THROW вам не нужно никаких хранимых процедур. Ваш обработчик CATCH становится таким же простым, как этот:

BEGIN CATCH
   IF @@trancount > 0 ROLLBACK TRANSACTION
   ;THROW
   RETURN 55555
END CATCH

Достоинство ;THROW в том, что сообщение об ошибке генерируется точно таким же, как и оригинальное сообщение. Если изначально было два сообщения об ошибках, оба сообщения воспроизводятся, что делает это выражение еще привлекательнее. Как и со всеми другими сообщениями об ошибках, ошибки, сгенерированные ;THROW, могут быть перехвачены внешним обработчиком CATCH и воспроизведены. Если обработчика CATCH нет, выполнение прерывается, поэтому оператор RETURN в данном случае оказывается не нужным. (Я все еще рекомендую оставлять его, на случай, если вы измените свое отношение к ;THROW позже).

Если у вас SQL Server 2012 или более поздняя версия, измените определение insert_data и outer_sp и попробуйте выполнить тесты еще раз. Результат в этот раз будет такой:

Msg 515, Level 16, State 2, Procedure insert_data, Line 5
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 2627, Level 14, State 1, Procedure insert_data, Line 6
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).

Имя процедуры и номер строки верны и нет никакого другого имени процедуры, которое может нас запутать. Также сохранены оригинальные номера ошибок.

В этом месте вы можете сказать себе: действительно ли Microsoft назвал команду ;THROW? Разве это не просто THROW? На самом деле, если вы посмотрите в Books Online, там не будет точки с запятой. Но точка с запятой должны быть. Официально они отделяют предыдущее выражение, но это опционально, и далеко не все используют точку с запятой в выражениях T-SQL. Более важно, что если вы пропустите точку с запятой перед THROW, то не будет никакой синтаксической ошибки. Но это повлияет на поведение при выполнении выражения, и это поведение будет непостижимым для непосвященных. При наличии активной транзакции вы получите сообщение об ошибке, которое будет полностью отличаться от оригинального. И еще хуже, что при отсутствии активной транзакции ошибка будет тихо выведена без обработки. Такая вещь, как пропуск точки с запятой, не должно иметь таких абсурдных последствий. Для уменьшения риска такого поведения, всегда думайте о команде как о ;THROW (с точкой с запятой).

Нельзя отрицать того, что ;THROW имеет свои преимущества, но точка с запятой не единственная ловушка этой команды. Если вы хотите использовать ее, я призываю вас прочитать по крайней мере вторую часть этой серии, где я раскрываю больше деталей о команде ;THROW. До этого момента, используйте error_handler_sp.

4.3. Использование SqlEventLog

Третий способ обработки ошибок – это использование SqlEventLog, который я описываю очень детально в третьей части. Здесь я лишь сделаю короткий обзор.

SqlEventLog предоставляет хранимую процедуру slog.catchhandler_sp, которая работает так же, как и error_handler_sp: она использует функции error_xxx() для сбора информации и выводит сообщение об ошибке, сохраняя всю информацию о ней. Вдобавок к этому, она логирует ошибку в таблицу splog.sqleventlog. В зависимости от типа приложения, которое у вас есть, эта таблица может быть очень ценным объектом.

Для использования SqlEventLog, ваш обработчик CATCH должен быть таким:

BEGIN CATCH
   IF @@trancount > 0 ROLLBACK TRANSACTION
   EXEC slog.catchhandler_sp @@procid
   RETURN 55555
END CATCH

@@procid возвращает идентификатор объекта текущей хранимой процедуры. Это то, что SqlEventLog использует для логирования информации в таблицу. Используя те же тестовые сценарии, получим результат их работы с использованием catchhandler_sp:

Msg 50000, Level 16, State 2, Procedure catchhandler_sp, Line 125
{515} Procedure insert_data, Line 5
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 50000, Level 14, State 1, Procedure catchhandler_sp, Line 125
{2627} Procedure insert_data, Line 6
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).

Как вы видите, сообщение об ошибке отформатировано немного не так, как это делает error_handler_sp, но основная идея такая же. Вот образец того, что было записано в таблицу slog.sqleventlog:

logid logdate errno severity logproc linenum msgtext
1 2015-01-25 22:40:24.393 515 16 insert_data 5 Cannot insert …
2 2015-01-25 22:40:24.395 2627 14 insert_data 6 Violation of …

Если вы хотите попробовать SqlEventLog, вы можете загрузить файл sqleventlog.zip. Инструкция по установке находится в третьей части, раздел Установка SqlEventLog.

5. Финальные замечания

Вы изучили основной образец для обработки ошибок и транзакций в хранимых процедурах. Он не идеален, но он должен работать в 90-95% вашего кода. Есть несколько ограничений, на которые стоит обратить внимание:

  1. Как мы видели, ошибки компиляции не могут быть перехвачены в той же процедуре, в которой они возникли, а только во внешней процедуре.
  2. Пример не работает с пользовательскими функциями, так как ни TRY-CATCH, ни RAISERROR нельзя в них использовать.
  3. Когда хранимая процедура на Linked Server вызывает ошибку, эта ошибка может миновать обработчик в хранимой процедуре на локальном сервере и отправиться напрямую клиенту.
  4. Когда процедура вызвана как INSERT-EXEC, вы получите неприятную ошибку, потому что ROLLBACK TRANSACTION не допускается в данном случае.
  5. Как упомянуто выше, если вы используете error_handler_sp или SqlEventLog, мы потеряете одно сообщение, когда SQL Server выдаст два сообщения для одной ошибки. При использовании ;THROW такой проблемы нет.

Я рассказываю об этих ситуациях более подробно в других статьях этой серии.

Перед тем как закончить, я хочу кратко коснуться триггеров и клиентского кода.

Триггеры

Пример для обработки ошибок в триггерах не сильно отличается от того, что используется в хранимых процедурах, за исключением одной маленькой детали: вы не должны использовать выражение RETURN (потому что RETURN не допускается использовать в триггерах).

С триггерами важно понимать, что они являются частью команды, которая запустила триггер, и в триггере вы находитесь внутри транзакции, даже если не используете BEGIN TRANSACTION.
Иногда я вижу на форумах людей, которые спрашивают, могут ли они написать триггер, который не откатывает в случае падения запустившую его команду. Ответ таков: нет способа сделать это надежно, поэтому не стоит даже пытаться. Если в этом есть необходимость, по возможности не следует использовать триггер вообще, а найти другое решение. Во второй и третьей частях я рассматриваю обработку ошибок в триггерах более подробно.

Клиентский код

У вас должна быть обработка ошибок в коде клиента, если он имеет доступ к базе. То есть вы должны всегда предполагать, что при любом вызове что-то может пойти не так. Как именно внедрить обработку ошибок, зависит от конкретной среды.

Здесь я только обращу внимание на важную вещь: реакцией на ошибку, возвращенную SQL Server, должно быть завершение запроса во избежание открытых бесхозных транзакций:

IF @@trancount > 0 ROLLBACK TRANSACTION

Это также применимо к знаменитому сообщению Timeout expired (которое является не сообщением от SQL Server, а от API).

6. Конец первой части

Это конец первой из трех частей серии. Если вы хотели изучить вопрос обработки ошибок быстро, вы можете закончить чтение здесь. Если вы настроены идти дальше, вам следует прочитать вторую часть, где наше путешествие по запутанным джунглям обработки ошибок и транзакций в SQL Server начинается по-настоящему.

… и не забывайте добавлять эту строку в начало ваших хранимых процедур:

SET XACT_ABORT, NOCOUNT ON

  • Remove From My Forums
  • Question

  • An error has occurred during report processing.

    • Cannot set the command text for data set ‘ScoreboardOLAP’.
      • Error during processing of the CommandText expression of dataset ‘ScoreboardOLAP’

    Can anyone help at all here?  I’ve seen about 10 articles on this one but none appear to be relevant.  I have a complex report comprising many sub-reports which runs successfully in a development environment.  When deployed to an environment which comprises a separate report sever and report server DB I get the above error even when I try and browse to any of the sub-reports.

    The sub-report is using an OLEDB connection to an SSAS DB and its command text is set as:-

    =Code.GetQueryString(parameters)

    Where GetQueryString is a function in the code section of the report which returns some MDX based on the supplied parameters.  I obviously know the function works because it works in development mode. 

    I have tried to determine what is going on from the logs but the only messages I get are those above.  I’ve set the data sources on the server up to use valid Windows Credentials stored on the server so I don’t believe the issue is one of authentication

    Any thoughts or tips in helping to diagnose the cause of the problem would be greatly appreciated.

Answers

  • Solved — and I’ve seen a number of other users with this issue so pay attention!!!!

    The problem is one of security.  The default security policy for ReportServer is NOT to allow code to be executed.  Therefore any references to Code.<method> within a report will not run in a default deployment environment.  This makes perfect sense if you think that users can create and publish their own reports onto report server and by using Code blocks, could easily write managed code to publish present information relating to the run-time environment on which the report is running. 

    However, and this is my rant!!! — why oh why oh why do people blindly follow OOD articles by respected industry thinkers relating to the management of exceptions.  I’ve seen so many articles talking about catching exceptions within the various layers of an application, wrapping them and then passing them up the exception chain.  This is exactly what seems to be happening with this problem i.e. the Code block cannot be executed — therefore throw an exception.  Unfortunately what then happens is that the various layers above catch this exception, wrap it up again and throw it on until at the top layer you end up with some non-sensical exception message such as

    Cannot set the command text for data set’

    Even with by examining the SSRS report server logs, you cannot see the inner exceptions and therefore cannot work out what is really going on.

    I compare this to Chinese whispers where at the top layer you end up with something totally non-sensical and unrelated to the error that actually occurred.  If you have to bubble up exceptions, at least make the exception stack visible.  Personally I believe that exceptions should only be caught when it makes sense to do so (i.e. there is some bespoke action to be taken based on the exception type), otherwise you end up spending signifcant amounts of time trying to work out what actually is going wrong.

    This is not the first time I’ve seen exceptions within .NET products not bubbling up correctly and leading to incorrect error presentation at the top layer. 

    Of course this is my personal opinion but I’ve been doing this sort of stuff for 25 years now and would like to think I’ve learnt a thing or two by now….

Понравилась статья? Поделить с друзьями:
  • Error during opengl initialization
  • Error during managed flush
  • Error during loading vbf форд фокус
  • Error during launcher start aion
  • Error during initialization ошибка инициализации miles sound system