Can't seem to find the right way to catch a MySQL index violation in a Grails app. Code from the controller:
try {
configurationInstance.save(flush: true) {
request.withFormat {...}
}
catch (JDBCException exception) {
flash.error = "This would be a duplicate attribute, please change the suffix."
render view: 'edit', model: [exception: exception]
}
When I provoke the error condition by submitting a duplicate value, the catch block is ignored and I get a 500 error page with these details:
URI /itools/configuration/save
Class com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException
Message Duplicate entry '1009303-photo-recommendable-exclusion-pattern.2-0' for key 'publisher_config_uk'
And in the console I've got:
ERROR errors.GrailsExceptionResolver - MySQLIntegrityConstraintViolationException occurred when processing request: [POST] /itools/configuration/save - parameters:
I've tried to catch
JDBCException
SQLError
SQLException
SQLDataException
SQLIntegrityConstraintViolationException
MySQLIntegrityConstraintViolationException
com.mysql.jdbc.exceptions.jdbc4.MySQLDataException
all to no avail. (FWIW I also applied a unique constraint on the attribute in question and it does nothing when it should cause a validation error. That's a completely different issue.)
What's the right way to do this?
Found it: it's DuplicateKeyException.
(I had to catch the generic Exception and see it's details to find this.)
Now I've got a new problem: upon trying to render or redirect I get "null id in itools.Configuration entry (don't flush the Session after an exception occurs)." This makes no sense to me -- the new entity was never saved to the DB because of the duplicate key, so why would a null ID object be a problem?
Related
I've been hitting the wall and haven't came up with any reasonable solution, so maybe someone will give it a try. I wrote simple service integrating with github, and having hard time to understand how should I work with exceptions in reactive word properly. Once I got expected 404 status error from Github I would like to throw my custom exception and present it to the client instead of valid response, I'm checking code statuses of response from github and the only thing I receive on my site is:
2018-06-26 21:45:08.286 WARN 8336 --- [ctor-http-nio-2]
.a.w.r.e.DefaultErrorWebExceptionHandler : Failed to handle request
[GET http://localhost:8080/repositories/sh1nen/no-exist]: Response
status 404
Here is my simple method responsible for making requests and handling error codes appropriately.
fun findSpecificOwnerRepository(owner: String, repositoryName: String) = webClient
.get()
.uri("/repos/$owner/$repositoryName")
.retrieve()
.onStatus({ httpStatus -> HttpStatus.NOT_FOUND == httpStatus }, { Mono.error(RepositoryNotFoundException(reason = "Repository $repositoryName not found.")) })
.onStatus({ httpStatus -> HttpStatus.SERVICE_UNAVAILABLE == httpStatus }, { Mono.error(RepositoryNotFoundException(reason = "Service unavailable.")) })
.bodyToMono(GithubRepositoryResponse::class.java)
Here is my custom exception which basically represents no resources on my site to represent:
internal class RepositoryNotFoundException(
status: HttpStatus = HttpStatus.NOT_FOUND,
reason: String? = null,
throwable: Throwable? = null) : ResponseStatusException(status, reason, throwable)
And the endpoint itself which I'm hitting to get the response:
#GetMapping("{owner}/{repositoryName}")
fun findSpecificOwnerRepository(#PathVariable owner: String, #PathVariable repositoryName: String) = githubClient
.findSpecificOwnerRepository(owner, repositoryName)
I would like to get 404 with a message which is hardcoded. Do I need any special #ExceptionHandler in controller to handle my custom exception ?
Is there any chance of implementing situation when for example github is not able to keep up with requests I am serving and throw in that case also some exception? How could it be implemented?
I'm not sure if you are actually missing anything for point 1), as the exception you extend should naturally result in 404 to your clients, if I recall correctly.
About point 2, it all depends on how your source handles rate limiting. In the case of GitHub, it will return a 403 once you hit rate limits, but you can be extra careful and check the custom headers as well. See https://developer.github.com/v3/#rate-limiting
So the simplest way it would be implemented is with onStatus. Alternatively, you can inspect the whole response and act accordingly by using exchange instead of retrieve, and flatMaping on the resulting Mono (that emits the whole server response).
I've read the Feathers book, so I know that to create an error response I simply instantiate the appropriate feathers-errors class:
import {BadRequest} from 'feathers-errors';
const errorResponse = new BadRequest(`foo`, `bar`);
However, I'm having difficulty returning that error response to the user. Even when I create an endpoint that does nothing but return an error response ...
class SomeService {
create(data) {
return new BadRequest(`foo`, `bar`);
}
}
it doesn't work: instead of getting an error response, I get no response, and inside the Chrome debugger I can see that the response is pending (until it eventually times out and becomes an ERR_EMPTY_RESPONSE).
I tried reading about Express error handling, and in the examples I saw people used next to wrap the the response. However, next comes from the error handler, and I'm not sure where in my Feathers code I can get that next function.
If anyone could help explain (using next or not) how I can return a complete, not pending, error response, I would greatly appreciate it.
Your services have to return a promise. If your code is not asynchronous you can turn it into a promise with Promise.resolve and Promise.reject:
class SomeService {
create(data) {
return Promise.reject(new BadRequest(`foo`, `bar`));
}
}
Also make sure you registered the Express error handler to get nicely formatted errors:
const errorHandler = require('feathers-errors/handler');
// Last in the chain
app.use(errorHandler);
There is also more information in the error handling chapter.
I have a website that displays a list of data from a database. I noticed the browser reporting a 500 Internal Server Error, but only in one case. Here's the controller method.
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult GetTouches(FormCollection collection)
{
try
{
List<p_SiteTouchSummary> pSiteTouchSummarys = ptsRepository.GetPSiteTouchSummarys().ToList();
return Json(new { wasSuccess = true, pSiteTouchSummarys });
}
catch (Exception ex)
{
Log.Error(ex, Request.Path, UserHelper.GetEmployeeLogin());
return Json(new { wasSuccess = false, message = "Error - Search failed" });
}
}
In debugging I found that it would reach the return, exist the method, and then never return to the javascript file that called it. The browser only takes about 1 second to report the 500 error, and it's not consistent, so I don't think it's a timeout.
Also, I modified the returned list with Take statements, and it works at 150, but not at 200. And if I do a Skip(150).Take(50) that also works. It seems to be that ~200 entries is somehow breaking it, but it's not reporting it being too big to deserialize.
Anyone know what is going on and a good way to fix it?
The JsonResult class does have a property(maxJsonLength), try changing it:
var jsonResult = Json(dataModel,
JsonRequestBehavior.AllowGet);
jsonResult.maxJsonLength = int.MaxValue;
return jsonResult;
or
<appSettings>
<add key="aspnet:MaxJsonDeserializerMembers" value="150000" />
</appSettings>
Status 500 = "Internal Server Error". Which is a catchall error for anything where the server should give you a reasonable reply but doesn't. For example, if your server code throws an exception that isn't handle otherwise, the server will likely handle it by returning status 500 to the caller.
Solution: 1. Complain to the people responsible for the server code. 2. The server people might be able to tell you exactly what triggers the error, so you avoid it. 3. They might not give you anything useful, so you change your requests in a way that you believe guarantees no status 500 error, and if you still get one then repeat the request requesting fewer data.
In Drupal 7.14, when i Index my Whole Site, Solr is showing following error:
AJAX HTTP error occurred. HTTP Result Code: 500 Debugging information follows.
Path: /batch?id=1938&op=do StatusText: Service unavailable (with message)
ResponseText: EntityMalformedException: Missing bundle property on entity of type taxonomy_term. in entity_extract_ids() (line 7539 of /project/path/includes/common.inc).
So when i look into the lines in /includes/common.inc (around lines: 7537):
// Explicitly fail for malformed entities missing the bundle property.
if (!isset($entity->{$info['entity keys']['bundle']}) || $entity->{$info['entity keys']['bundle']} === '') {
throw new EntityMalformedException(t('Missing bundle property on entity of type #entity_type.', array('#entity_type' => $entity_type)));
}
What is that chunk of code (in common.inc) is doing actually please?
How can i overcome that error?
Please, try this module https://drupal.org/project/taxonomy_orphanage it will delete all empty bundles.
I have an ASP.NET MVC 3 application where I'm making an AJAX call and expecting a JSON result back. I'm using ELMAH to log errors. While testing I had an unexpected error. ELMAH logged the error, but my client side script doesn't because the result is not proper JSON now. If I handle all errors in the controller to return a proper JSON result, then the error doesn't get logged by ELMAH. I know I can call ELMAH specifically to log the error, but I rather like that I don't have to do that anywhere else.
Can anyone clarify the 'proper' way to handle this scenario?
for example
try
{
//service.dosomethingwitherror();
return new JsonResult { Data = new { result = true, message = "Success." } };
}
catch (Exception ex)
{
return new JsonResult { Data = new { result = true, message = "Failed." } };
}
Since I'm 'handling' this, ELMAH doesn't log. If I don't handle this my client won't get JSON...
You can use the ErrorSignal class to log manually. This will perform all configured elmah operations (log, mail, tweet, etc).
ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
See http://code.google.com/p/elmah/wiki/DotNetSlackersArticle#Signaling_errors for more information.
If you really don't like adding that code to your controller, you could not catch the exception server side and handle the ajax error event in your javascript.